Refactored Common & JVM IR Phaser
This commit is contained in:
+109
-29
@@ -8,7 +8,9 @@ package org.jetbrains.kotlin.backend.common
|
|||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||||
import org.jetbrains.kotlin.config.CompilerConfiguration
|
import org.jetbrains.kotlin.config.CompilerConfiguration
|
||||||
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
import org.jetbrains.kotlin.config.CompilerConfigurationKey
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.util.dump
|
||||||
|
import kotlin.system.measureTimeMillis
|
||||||
|
|
||||||
interface CompilerPhase<in Context : BackendContext, Data> {
|
interface CompilerPhase<in Context : BackendContext, Data> {
|
||||||
val name: String
|
val name: String
|
||||||
@@ -31,13 +33,21 @@ class CompilerPhases(private val phaseList: List<AnyPhase>, config: CompilerConf
|
|||||||
val toDumpStateBefore: Set<AnyPhase>
|
val toDumpStateBefore: Set<AnyPhase>
|
||||||
val toDumpStateAfter: Set<AnyPhase>
|
val toDumpStateAfter: Set<AnyPhase>
|
||||||
|
|
||||||
|
val toValidateStateBefore: Set<AnyPhase>
|
||||||
|
val toValidateStateAfter: Set<AnyPhase>
|
||||||
|
|
||||||
init {
|
init {
|
||||||
with(CommonConfigurationKeys) {
|
with(CommonConfigurationKeys) {
|
||||||
val beforeSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE_BEFORE)
|
val beforeDumpSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE_BEFORE)
|
||||||
val afterSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE_AFTER)
|
val afterDumpSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE_AFTER)
|
||||||
val bothSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE)
|
val bothDumpSet = phaseSetFromConfiguration(config, PHASES_TO_DUMP_STATE)
|
||||||
toDumpStateBefore = beforeSet + bothSet
|
toDumpStateBefore = beforeDumpSet + bothDumpSet
|
||||||
toDumpStateAfter = afterSet + bothSet
|
toDumpStateAfter = afterDumpSet + bothDumpSet
|
||||||
|
val beforeValidateSet = phaseSetFromConfiguration(config, PHASES_TO_VALIDATE_BEFORE)
|
||||||
|
val afterValidateSet = phaseSetFromConfiguration(config, PHASES_TO_VALIDATE_AFTER)
|
||||||
|
val bothValidateSet = phaseSetFromConfiguration(config, PHASES_TO_VALIDATE)
|
||||||
|
toValidateStateBefore = beforeValidateSet + bothValidateSet
|
||||||
|
toValidateStateAfter = afterValidateSet + bothValidateSet
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -70,13 +80,95 @@ class CompilerPhases(private val phaseList: List<AnyPhase>, config: CompilerConf
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
interface PhaseRunner<Context : BackendContext, Data> {
|
interface PhaseRunner<Context : BackendContext, Data> {
|
||||||
fun reportBefore(phase: CompilerPhase<Context, Data>, depth: Int, context: Context, data: Data)
|
fun runBefore(phase: CompilerPhase<Context, Data>, depth: Int, context: Context, data: Data)
|
||||||
fun runBody(phase: CompilerPhase<Context, Data>, context: Context, source: Data): Data
|
fun runBody(phase: CompilerPhase<Context, Data>, context: Context, source: Data): Data
|
||||||
fun reportAfter(phase: CompilerPhase<Context, Data>, depth: Int, context: Context, data: Data)
|
fun runAfter(phase: CompilerPhase<Context, Data>, depth: Int, context: Context, data: Data)
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class DefaultIrPhaseRunner<Context : CommonBackendContext, Data : IrElement>(private val validator: (data: Data, context: Context) -> Unit = { _, _ -> }) :
|
||||||
|
PhaseRunner<Context, Data> {
|
||||||
|
|
||||||
|
enum class BeforeOrAfter { BEFORE, AFTER }
|
||||||
|
|
||||||
|
abstract val startPhaseMarker: CompilerPhase<Context, Data>
|
||||||
|
abstract val endPhaseMarker: CompilerPhase<Context, Data>
|
||||||
|
|
||||||
|
private var inVerbosePhase = false
|
||||||
|
|
||||||
|
final override fun runBefore(phase: CompilerPhase<Context, Data>, depth: Int, context: Context, data: Data) {
|
||||||
|
checkAndRun(phase, phases(context).toDumpStateBefore) { dumpElement(data, phase, context, BeforeOrAfter.BEFORE) }
|
||||||
|
checkAndRun(phase, phases(context).toValidateStateBefore) { validator(data, context) }
|
||||||
|
}
|
||||||
|
|
||||||
|
final override fun runBody(phase: CompilerPhase<Context, Data>, context: Context, source: Data): Data {
|
||||||
|
val runner = when {
|
||||||
|
phase === startPhaseMarker -> ::justRun
|
||||||
|
phase === endPhaseMarker -> ::justRun
|
||||||
|
needProfiling(context) -> ::runAndProfile
|
||||||
|
else -> ::justRun
|
||||||
|
}
|
||||||
|
|
||||||
|
inVerbosePhase = phase in phases(context).verbose
|
||||||
|
|
||||||
|
val result = runner(phase, context, source)
|
||||||
|
|
||||||
|
inVerbosePhase = false
|
||||||
|
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
final override fun runAfter(phase: CompilerPhase<Context, Data>, depth: Int, context: Context, data: Data) {
|
||||||
|
checkAndRun(phase, phases(context).toDumpStateAfter) { dumpElement(data, phase, context, BeforeOrAfter.AFTER) }
|
||||||
|
checkAndRun(phase, phases(context).toValidateStateAfter) { validator(data, context) }
|
||||||
|
}
|
||||||
|
|
||||||
|
open fun separator(title: String) = println("\n\n--- $title ----------------------\n")
|
||||||
|
|
||||||
|
protected abstract fun phases(context: Context): CompilerPhases
|
||||||
|
protected abstract fun elementName(input: Data): String
|
||||||
|
protected abstract fun configuration(context: Context): CompilerConfiguration
|
||||||
|
|
||||||
|
private fun needProfiling(context: Context) = configuration(context).getBoolean(CommonConfigurationKeys.PROFILE_PHASES)
|
||||||
|
|
||||||
|
private fun shouldBeDumped(context: Context, input: Data) =
|
||||||
|
elementName(input) !in configuration(context).get(CommonConfigurationKeys.EXCLUDED_ELEMENTS_FROM_DUMPING, emptySet())
|
||||||
|
|
||||||
|
private fun checkAndRun(phase: CompilerPhase<Context, Data>, set: Set<AnyPhase>, block: () -> Unit) {
|
||||||
|
if (phase in set) block()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun dumpElement(input: Data, phase: CompilerPhase<Context, Data>, context: Context, beforeOrAfter: BeforeOrAfter) {
|
||||||
|
// Exclude nonsensical combinations
|
||||||
|
if (phase === startPhaseMarker && beforeOrAfter == BeforeOrAfter.AFTER) return
|
||||||
|
if (phase === endPhaseMarker && beforeOrAfter == BeforeOrAfter.BEFORE) return
|
||||||
|
|
||||||
|
if (!shouldBeDumped(context, input)) return
|
||||||
|
|
||||||
|
val title = when (phase) {
|
||||||
|
startPhaseMarker -> "IR for ${elementName(input)} at the start of lowering process"
|
||||||
|
endPhaseMarker -> "IR for ${elementName(input)} at the end of lowering process"
|
||||||
|
else -> {
|
||||||
|
val beforeOrAfterStr = beforeOrAfter.name.toLowerCase()
|
||||||
|
"IR for ${elementName(input)} $beforeOrAfterStr ${phase.description}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
separator(title)
|
||||||
|
println(input.dump())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun runAndProfile(phase: CompilerPhase<Context, Data>, context: Context, source: Data): Data {
|
||||||
|
var result: Data = source
|
||||||
|
val msec = measureTimeMillis { result = phase.invoke(context, source) }
|
||||||
|
println("${phase.description}: $msec msec")
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun justRun(phase: CompilerPhase<Context, Data>, context: Context, source: Data) =
|
||||||
|
phase.invoke(context, source)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* We assume that `element` is being modified by each phase, retaining its identity in the process. */
|
|
||||||
class CompilerPhaseManager<Context : BackendContext, Data>(
|
class CompilerPhaseManager<Context : BackendContext, Data>(
|
||||||
val context: Context,
|
val context: Context,
|
||||||
val phases: CompilerPhases,
|
val phases: CompilerPhases,
|
||||||
@@ -111,39 +203,27 @@ class CompilerPhaseManager<Context : BackendContext, Data>(
|
|||||||
|
|
||||||
previousPhases.add(phase)
|
previousPhases.add(phase)
|
||||||
|
|
||||||
phaseRunner.reportBefore(phase, depth, context, source)
|
phaseRunner.runBefore(phase, depth, context, source)
|
||||||
val result = phaseRunner.runBody(phase, context, source)
|
val result = phaseRunner.runBody(phase, context, source)
|
||||||
phaseRunner.reportAfter(phase, depth, context, result)
|
phaseRunner.runAfter(phase, depth, context, result)
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun <Context : BackendContext> makePhase(
|
fun <Context : BackendContext, Data> makePhase(
|
||||||
loweringConstructor: (Context) -> FileLoweringPass,
|
lowering: (Context, Data) -> Unit,
|
||||||
description: String,
|
description: String,
|
||||||
name: String,
|
name: String,
|
||||||
prerequisite: Set<CompilerPhase<*, *>> = emptySet()
|
prerequisite: Set<CompilerPhase<*, *>> = emptySet()
|
||||||
) = object : CompilerPhase<Context, IrFile> {
|
) = object : CompilerPhase<Context, Data> {
|
||||||
override val name = name
|
override val name = name
|
||||||
override val description = description
|
override val description = description
|
||||||
override val prerequisite = prerequisite
|
override val prerequisite = prerequisite
|
||||||
|
|
||||||
override fun invoke(context: Context, input: IrFile): IrFile {
|
override fun invoke(context: Context, input: Data): Data {
|
||||||
loweringConstructor(context).lower(input)
|
lowering(context, input)
|
||||||
return input
|
return input
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
object IrFileStartPhase : CompilerPhase<BackendContext, IrFile> {
|
override fun toString() = "Compiler Phase @$name"
|
||||||
override val name = "IrFileStart"
|
|
||||||
override val description = "State at start of IrFile lowering"
|
|
||||||
override val prerequisite = emptySet()
|
|
||||||
override fun invoke(context: BackendContext, input: IrFile) = input
|
|
||||||
}
|
|
||||||
|
|
||||||
object IrFileEndPhase : CompilerPhase<BackendContext, IrFile> {
|
|
||||||
override val name = "IrFileEnd"
|
|
||||||
override val description = "State at end of IrFile lowering"
|
|
||||||
override val prerequisite = emptySet()
|
|
||||||
override fun invoke(context: BackendContext, input: IrFile) = input
|
|
||||||
}
|
}
|
||||||
-10
@@ -37,16 +37,6 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
|||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
fun makeDefaultArgumentStubPhase(skipInlineMethods: Boolean) = object : CompilerPhase<CommonBackendContext, IrFile> {
|
|
||||||
override val name = "DefaultArgumentsStubGenerator"
|
|
||||||
override val description = "Generate synthetic stubs for functions with default parameter values"
|
|
||||||
|
|
||||||
override fun invoke(context: CommonBackendContext, input: IrFile): IrFile {
|
|
||||||
DefaultArgumentStubGenerator(context, skipInlineMethods).lower(input)
|
|
||||||
return input
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TODO: fix expect/actual default parameters
|
// TODO: fix expect/actual default parameters
|
||||||
|
|
||||||
open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext, private val skipInlineMethods: Boolean = true) :
|
open class DefaultArgumentStubGenerator constructor(val context: CommonBackendContext, private val skipInlineMethods: Boolean = true) :
|
||||||
|
|||||||
-11
@@ -34,17 +34,6 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
||||||
|
|
||||||
fun makeInitializersPhase(declarationOrigin: IrDeclarationOrigin, clinitNeeded: Boolean) = object :
|
|
||||||
CompilerPhase<CommonBackendContext, IrFile> {
|
|
||||||
override val name = "Initializers"
|
|
||||||
override val description = "Handle initializer statements"
|
|
||||||
|
|
||||||
override fun invoke(context: CommonBackendContext, input: IrFile): IrFile {
|
|
||||||
InitializersLowering(context, declarationOrigin, clinitNeeded).lower(input)
|
|
||||||
return input
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
object SYNTHESIZED_INIT_BLOCK: IrStatementOriginImpl("SYNTHESIZED_INIT_BLOCK")
|
object SYNTHESIZED_INIT_BLOCK: IrStatementOriginImpl("SYNTHESIZED_INIT_BLOCK")
|
||||||
|
|
||||||
class InitializersLowering(
|
class InitializersLowering(
|
||||||
|
|||||||
-12
@@ -28,12 +28,6 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
|||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
val InnerClassesPhase = makePhase(
|
|
||||||
::InnerClassesLowering,
|
|
||||||
name = "InnerClasses",
|
|
||||||
description = "Move inner classes to toplevel"
|
|
||||||
)
|
|
||||||
|
|
||||||
class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
||||||
override fun lower(irClass: IrClass) {
|
override fun lower(irClass: IrClass) {
|
||||||
InnerClassTransformer(irClass).lowerInnerClass()
|
InnerClassTransformer(irClass).lowerInnerClass()
|
||||||
@@ -175,12 +169,6 @@ class InnerClassesLowering(val context: BackendContext) : ClassLoweringPass {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val InnerClassConstructorCallsPhase = makePhase(
|
|
||||||
::InnerClassConstructorCallsLowering,
|
|
||||||
name = "InnerClassConstructorCalls",
|
|
||||||
description = "Handle constructor calls for inner classes"
|
|
||||||
)
|
|
||||||
|
|
||||||
class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLoweringPass {
|
class InnerClassConstructorCallsLowering(val context: BackendContext) : BodyLoweringPass {
|
||||||
override fun lower(irBody: IrBody) {
|
override fun lower(irBody: IrBody) {
|
||||||
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
irBody.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||||
|
|||||||
-6
@@ -38,12 +38,6 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
val KCallableNamePropertyPhase = makePhase(
|
|
||||||
::KCallableNamePropertyLowering,
|
|
||||||
name = "KCallableNameProperty",
|
|
||||||
description = "Replace name references for callables with constants"
|
|
||||||
)
|
|
||||||
|
|
||||||
class KCallableNamePropertyLowering(val context: BackendContext) : FileLoweringPass {
|
class KCallableNamePropertyLowering(val context: BackendContext) : FileLoweringPass {
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.transformChildrenVoid(KCallableNamePropertyTransformer(this))
|
irFile.transformChildrenVoid(KCallableNamePropertyTransformer(this))
|
||||||
|
|||||||
+1
-26
@@ -40,20 +40,6 @@ import org.jetbrains.kotlin.name.NameUtils
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.parents
|
import org.jetbrains.kotlin.resolve.descriptorUtil.parents
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
val LocalDeclarationsPhase = makePhase(
|
|
||||||
::LocalDeclarationsLowering,
|
|
||||||
name = "LocalDeclarations",
|
|
||||||
description = "Move local declarations to classes",
|
|
||||||
prerequisite = setOf(SharedVariablesPhase)
|
|
||||||
)
|
|
||||||
|
|
||||||
val JvmLocalDeclarationsPhase = makePhase(
|
|
||||||
::JvmLocalDeclarationsLowering,
|
|
||||||
name = "JvmLocalDeclarations",
|
|
||||||
description = "Move local declarations to classes",
|
|
||||||
prerequisite = setOf(SharedVariablesPhase)
|
|
||||||
)
|
|
||||||
|
|
||||||
interface LocalNameProvider {
|
interface LocalNameProvider {
|
||||||
fun localName(descriptor: DeclarationDescriptor): String =
|
fun localName(descriptor: DeclarationDescriptor): String =
|
||||||
descriptor.name.asString()
|
descriptor.name.asString()
|
||||||
@@ -71,18 +57,7 @@ val IrDeclaration.parents: Sequence<IrDeclarationParent>
|
|||||||
|
|
||||||
object BOUND_VALUE_PARAMETER: IrDeclarationOriginImpl("BOUND_VALUE_PARAMETER")
|
object BOUND_VALUE_PARAMETER: IrDeclarationOriginImpl("BOUND_VALUE_PARAMETER")
|
||||||
|
|
||||||
class JvmLocalDeclarationsLowering(context: BackendContext) :
|
class LocalDeclarationsLowering(
|
||||||
LocalDeclarationsLowering(
|
|
||||||
context,
|
|
||||||
object : LocalNameProvider {
|
|
||||||
override fun localName(descriptor: DeclarationDescriptor): String =
|
|
||||||
NameUtils.sanitizeAsJavaIdentifier(super.localName(descriptor))
|
|
||||||
},
|
|
||||||
Visibilities.PUBLIC, //TODO properly figure out visibility
|
|
||||||
true
|
|
||||||
)
|
|
||||||
|
|
||||||
open class LocalDeclarationsLowering(
|
|
||||||
val context: BackendContext,
|
val context: BackendContext,
|
||||||
val localNameProvider: LocalNameProvider = LocalNameProvider.DEFAULT,
|
val localNameProvider: LocalNameProvider = LocalNameProvider.DEFAULT,
|
||||||
val loweredConstructorVisibility: Visibility = Visibilities.PRIVATE,
|
val loweredConstructorVisibility: Visibility = Visibilities.PRIVATE,
|
||||||
|
|||||||
-6
@@ -18,12 +18,6 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|||||||
import org.jetbrains.kotlin.utils.addIfNotNull
|
import org.jetbrains.kotlin.utils.addIfNotNull
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
val PropertiesPhase = makePhase(
|
|
||||||
::PropertiesLowering,
|
|
||||||
name = "Properties",
|
|
||||||
description = "move fields and accessors for properties to their classes"
|
|
||||||
)
|
|
||||||
|
|
||||||
class PropertiesLowering() : IrElementTransformerVoid(), FileLoweringPass {
|
class PropertiesLowering() : IrElementTransformerVoid(), FileLoweringPass {
|
||||||
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
||||||
|
|
||||||
|
|||||||
-6
@@ -34,12 +34,6 @@ import org.jetbrains.kotlin.ir.util.dump
|
|||||||
import org.jetbrains.kotlin.ir.visitors.*
|
import org.jetbrains.kotlin.ir.visitors.*
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
val SharedVariablesPhase = makePhase(
|
|
||||||
::SharedVariablesLowering,
|
|
||||||
name = "SharedVariables",
|
|
||||||
description = "Transform shared variables"
|
|
||||||
)
|
|
||||||
|
|
||||||
class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPass {
|
class SharedVariablesLowering(val context: BackendContext) : FunctionLoweringPass {
|
||||||
override fun lower(irFunction: IrFunction) {
|
override fun lower(irFunction: IrFunction) {
|
||||||
SharedVariablesTransformer(irFunction).lowerSharedVariables()
|
SharedVariablesTransformer(irFunction).lowerSharedVariables()
|
||||||
|
|||||||
-6
@@ -27,12 +27,6 @@ import org.jetbrains.kotlin.ir.util.getArgumentsWithIr
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
|
||||||
val TailrecPhase = makePhase(
|
|
||||||
::TailrecLowering,
|
|
||||||
name = "Tailrec",
|
|
||||||
description = "Handle tailrec calls"
|
|
||||||
)
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This pass lowers tail recursion calls in `tailrec` functions.
|
* This pass lowers tail recursion calls in `tailrec` functions.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -18,63 +18,10 @@ package org.jetbrains.kotlin.backend.jvm
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.BackendContext
|
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.CompilerPhase
|
import org.jetbrains.kotlin.backend.common.CompilerPhase
|
||||||
import org.jetbrains.kotlin.backend.common.IrFileEndPhase
|
|
||||||
import org.jetbrains.kotlin.backend.common.IrFileStartPhase
|
|
||||||
import org.jetbrains.kotlin.backend.common.lower.*
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.*
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
|
|
||||||
val jvmPhases = listOf(
|
|
||||||
IrFileStartPhase,
|
|
||||||
|
|
||||||
JvmCoercionToUnitPhase,
|
|
||||||
FileClassPhase,
|
|
||||||
KCallableNamePropertyPhase,
|
|
||||||
|
|
||||||
makeLateinitPhase(true),
|
|
||||||
|
|
||||||
MoveCompanionObjectFieldsPhase,
|
|
||||||
ConstAndJvmFieldPropertiesPhase,
|
|
||||||
PropertiesPhase,
|
|
||||||
AnnotationPhase,
|
|
||||||
|
|
||||||
makeDefaultArgumentStubPhase(false),
|
|
||||||
|
|
||||||
InterfacePhase,
|
|
||||||
InterfaceDelegationPhase,
|
|
||||||
SharedVariablesPhase,
|
|
||||||
|
|
||||||
makePatchParentsPhase(1),
|
|
||||||
|
|
||||||
JvmLocalDeclarationsPhase,
|
|
||||||
CallableReferencePhase,
|
|
||||||
FunctionNVarargInvokePhase,
|
|
||||||
|
|
||||||
InnerClassesPhase,
|
|
||||||
InnerClassConstructorCallsPhase,
|
|
||||||
|
|
||||||
makePatchParentsPhase(2),
|
|
||||||
|
|
||||||
EnumClassPhase,
|
|
||||||
ObjectClassPhase,
|
|
||||||
makeInitializersPhase(JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, true),
|
|
||||||
SingletonReferencesPhase,
|
|
||||||
SyntheticAccessorPhase,
|
|
||||||
BridgePhase,
|
|
||||||
JvmOverloadsAnnotationPhase,
|
|
||||||
JvmStaticAnnotationPhase,
|
|
||||||
StaticDefaultFunctionPhase,
|
|
||||||
|
|
||||||
TailrecPhase,
|
|
||||||
ToArrayPhase,
|
|
||||||
|
|
||||||
makePatchParentsPhase(3),
|
|
||||||
|
|
||||||
IrFileEndPhase
|
|
||||||
)
|
|
||||||
|
|
||||||
fun makePatchParentsPhase(number: Int) = object : CompilerPhase<BackendContext, IrFile> {
|
fun makePatchParentsPhase(number: Int) = object : CompilerPhase<BackendContext, IrFile> {
|
||||||
override val name: String = "PatchParents$number"
|
override val name: String = "PatchParents$number"
|
||||||
override val description: String = "Patch parent references in IrFile, pass $number"
|
override val description: String = "Patch parent references in IrFile, pass $number"
|
||||||
@@ -91,7 +38,7 @@ class JvmLower(val context: JvmBackendContext) {
|
|||||||
var state = irFile
|
var state = irFile
|
||||||
// TODO run lowering passes as callbacks in bottom-up visitor
|
// TODO run lowering passes as callbacks in bottom-up visitor
|
||||||
|
|
||||||
context.rootPhaseManager(irFile).apply {
|
context.rootPhaseManager(irFile).apply {
|
||||||
for (jvmPhase in jvmPhases) {
|
for (jvmPhase in jvmPhases) {
|
||||||
state = phase(jvmPhase, context, state)
|
state = phase(jvmPhase, context, state)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,77 +0,0 @@
|
|||||||
/*
|
|
||||||
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
|
||||||
* that can be found in the license/LICENSE.txt file.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm
|
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.*
|
|
||||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.name
|
|
||||||
import org.jetbrains.kotlin.ir.util.dump
|
|
||||||
import kotlin.system.measureTimeMillis
|
|
||||||
|
|
||||||
enum class BeforeOrAfter { BEFORE, AFTER }
|
|
||||||
|
|
||||||
object JvmPhaseRunner : PhaseRunner<JvmBackendContext, IrFile> {
|
|
||||||
override fun reportBefore(phase: CompilerPhase<JvmBackendContext, IrFile>, depth: Int, context: JvmBackendContext, data: IrFile) {
|
|
||||||
if (phase in context.phases.toDumpStateBefore) {
|
|
||||||
dumpFile(data, phase, BeforeOrAfter.BEFORE)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun runBody(phase: CompilerPhase<JvmBackendContext, IrFile>, context: JvmBackendContext, source: IrFile): IrFile {
|
|
||||||
val runner = when {
|
|
||||||
phase === IrFileStartPhase -> ::justRun
|
|
||||||
phase === IrFileEndPhase -> ::justRun
|
|
||||||
(context.state.configuration.get(CommonConfigurationKeys.PROFILE_PHASES) == true) -> ::runAndProfile
|
|
||||||
else -> ::justRun
|
|
||||||
}
|
|
||||||
|
|
||||||
context.inVerbosePhase = (phase in context.phases.verbose)
|
|
||||||
|
|
||||||
val result = runner(phase, context, source)
|
|
||||||
|
|
||||||
context.inVerbosePhase = false
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun reportAfter(phase: CompilerPhase<JvmBackendContext, IrFile>, depth: Int, context: JvmBackendContext, data: IrFile) {
|
|
||||||
if (phase in context.phases.toDumpStateAfter) {
|
|
||||||
dumpFile(data, phase, BeforeOrAfter.AFTER)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun runAndProfile(phase: CompilerPhase<JvmBackendContext, IrFile>, context: JvmBackendContext, source: IrFile): IrFile {
|
|
||||||
var result: IrFile = source
|
|
||||||
val msec = measureTimeMillis { result = phase.invoke(context, source) }
|
|
||||||
println("${phase.description}: $msec msec")
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun justRun(phase: CompilerPhase<JvmBackendContext, IrFile>, context: JvmBackendContext, source: IrFile) =
|
|
||||||
phase.invoke(context, source)
|
|
||||||
|
|
||||||
private fun separator(title: String) {
|
|
||||||
println("\n\n--- $title ----------------------\n")
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun dumpFile(irFile: IrFile, phase: CompilerPhase<JvmBackendContext, IrFile>, beforeOrAfter: BeforeOrAfter) {
|
|
||||||
// Exclude nonsensical combinations
|
|
||||||
if (phase === IrFileStartPhase && beforeOrAfter == BeforeOrAfter.AFTER) return
|
|
||||||
if (phase === IrFileEndPhase && beforeOrAfter == BeforeOrAfter.BEFORE) return
|
|
||||||
|
|
||||||
val title = when (phase) {
|
|
||||||
IrFileStartPhase -> "IR for ${irFile.name} at the start of lowering process"
|
|
||||||
IrFileEndPhase -> "IR for ${irFile.name} at the end of lowering process"
|
|
||||||
else -> {
|
|
||||||
val beforeOrAfterStr = beforeOrAfter.name.toLowerCase()
|
|
||||||
"IR for ${irFile.name} $beforeOrAfterStr ${phase.description}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
separator(title)
|
|
||||||
println(irFile.dump())
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,275 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.jvm
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.BackendContext
|
||||||
|
import org.jetbrains.kotlin.backend.common.CompilerPhase
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.*
|
||||||
|
import org.jetbrains.kotlin.backend.common.makePhase
|
||||||
|
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.lower.*
|
||||||
|
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
|
||||||
|
import org.jetbrains.kotlin.descriptors.Visibilities
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.name.NameUtils
|
||||||
|
|
||||||
|
object IrFileStartPhase : CompilerPhase<BackendContext, IrFile> {
|
||||||
|
override val name = "IrFileStart"
|
||||||
|
override val description = "State at start of IrFile lowering"
|
||||||
|
override val prerequisite = emptySet()
|
||||||
|
override fun invoke(context: BackendContext, input: IrFile) = input
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun makeJvmPhase(
|
||||||
|
lowering: (JvmBackendContext, IrFile) -> Unit,
|
||||||
|
description: String,
|
||||||
|
name: String,
|
||||||
|
prerequisite: Set<CompilerPhase<JvmBackendContext, IrFile>> = emptySet()
|
||||||
|
) = makePhase(lowering, description, name, prerequisite)
|
||||||
|
|
||||||
|
private val JvmCoercionToUnitPhase = makeJvmPhase(
|
||||||
|
{ context, file -> JvmCoercionToUnitPatcher(context).lower(file) },
|
||||||
|
name = "JvmCoercionToUnit",
|
||||||
|
description = "Insert conversions to unit after IrCalls where needed"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val FileClassPhase = makeJvmPhase(
|
||||||
|
{ context, file -> FileClassLowering(context).lower(file) },
|
||||||
|
name = "FileClass",
|
||||||
|
description = "Put file level function and property declaration into a class"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val KCallableNamePropertyPhase = makeJvmPhase(
|
||||||
|
{ context, file -> KCallableNamePropertyLowering(context).lower(file) },
|
||||||
|
name = "KCallableNameProperty",
|
||||||
|
description = "Replace name references for callables with constants"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val LateinitPhase = makeJvmPhase(
|
||||||
|
{ context, file -> LateinitLowering(context, true).lower(file) },
|
||||||
|
name = "Lateinit",
|
||||||
|
description = "Insert checks for lateinit field references"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val MoveCompanionObjectFieldsPhase = makeJvmPhase(
|
||||||
|
{ context, file -> MoveCompanionObjectFieldsLowering(context).runOnFilePostfix(file) },
|
||||||
|
name = "MoveCompanionObjectFields",
|
||||||
|
description = "Move companion object fields to static fields of companion's owner"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val ConstAndJvmFieldPropertiesPhase = makeJvmPhase(
|
||||||
|
{ context, file -> ConstAndJvmFieldPropertiesLowering(context).lower(file) },
|
||||||
|
name = "ConstAndJvmFieldProperties",
|
||||||
|
description = "Substitute calls to const and Jvm>Field properties with const/field access"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val PropertiesPhase = makeJvmPhase(
|
||||||
|
{ context, file -> PropertiesLowering(context).lower(file) },
|
||||||
|
name = "Properties",
|
||||||
|
description = "move fields and accessors for properties to their classes"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val AnnotationPhase = makeJvmPhase(
|
||||||
|
{ _, file -> AnnotationLowering().lower(file) },
|
||||||
|
name = "Annotation",
|
||||||
|
description = "Remove constructors from annotation classes"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val DefaultArgumentStubPhase = makeJvmPhase(
|
||||||
|
{ context, file -> DefaultArgumentStubGenerator(context, false).lower(file) },
|
||||||
|
name = "DefaultArgumentsStubGenerator",
|
||||||
|
description = "Generate synthetic stubs for functions with default parameter values"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val InterfacePhase = makeJvmPhase(
|
||||||
|
{ context, file -> InterfaceLowering(context).lower(file) },
|
||||||
|
name = "Interface",
|
||||||
|
description = "Move default implementations of interface members to DefaultImpls class"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val InterfaceDelegationPhase = makeJvmPhase(
|
||||||
|
{ context, file -> InterfaceDelegationLowering(context).lower(file) },
|
||||||
|
name = "InterfaceDelegation",
|
||||||
|
description = "Delegate calls to interface members with default implementations to DefaultImpls"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val SharedVariablesPhase = makeJvmPhase(
|
||||||
|
{ context, file -> SharedVariablesLowering(context).lower(file) },
|
||||||
|
name = "SharedVariables",
|
||||||
|
description = "Transform shared variables"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val LocalDeclarationsPhase = makeJvmPhase(
|
||||||
|
{ context, data ->
|
||||||
|
LocalDeclarationsLowering(context, object : LocalNameProvider {
|
||||||
|
override fun localName(descriptor: DeclarationDescriptor): String =
|
||||||
|
NameUtils.sanitizeAsJavaIdentifier(super.localName(descriptor))
|
||||||
|
}, Visibilities.PUBLIC, true).lower(data)
|
||||||
|
},
|
||||||
|
name = "JvmLocalDeclarations",
|
||||||
|
description = "Move local declarations to classes",
|
||||||
|
prerequisite = setOf(SharedVariablesPhase)
|
||||||
|
)
|
||||||
|
|
||||||
|
private val CallableReferencePhase = makeJvmPhase(
|
||||||
|
{ context, file -> CallableReferenceLowering(context).lower(file) },
|
||||||
|
name = "CallableReference",
|
||||||
|
description = "Handle callable references"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val FunctionNVarargInvokePhase = makeJvmPhase(
|
||||||
|
{ context, file -> FunctionNVarargInvokeLowering(context).lower(file) },
|
||||||
|
name = "FunctionNVarargInvoke",
|
||||||
|
description = "Handle invoke functions with large number of arguments"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val InnerClassesPhase = makeJvmPhase(
|
||||||
|
{ context, file -> InnerClassesLowering(context).lower(file) },
|
||||||
|
name = "InnerClasses",
|
||||||
|
description = "Move inner classes to toplevel"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val InnerClassConstructorCallsPhase = makeJvmPhase(
|
||||||
|
{ context, file -> InnerClassConstructorCallsLowering(context).lower(file) },
|
||||||
|
name = "InnerClassConstructorCalls",
|
||||||
|
description = "Handle constructor calls for inner classes"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val EnumClassPhase = makeJvmPhase(
|
||||||
|
{ context, file -> EnumClassLowering(context).lower(file) },
|
||||||
|
name = "EnumClass",
|
||||||
|
description = "Handle enum classes"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val ObjectClassPhase = makeJvmPhase(
|
||||||
|
{ context, file -> ObjectClassLowering(context).lower(file) },
|
||||||
|
name = "ObjectClass",
|
||||||
|
description = "Handle object classes"
|
||||||
|
)
|
||||||
|
|
||||||
|
private val InitializersPhase = makeJvmPhase(
|
||||||
|
{ context, file -> InitializersLowering(context, JvmLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, true).lower(file) },
|
||||||
|
name = "Initializers",
|
||||||
|
description = "Handle initializer statements"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val SingletonReferencesPhase = makeJvmPhase(
|
||||||
|
{ context, file -> SingletonReferencesLowering(context).lower(file) },
|
||||||
|
name = "SingletonReferences",
|
||||||
|
description = "Handle singleton references"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val SyntheticAccessorPhase = makeJvmPhase(
|
||||||
|
{ context, file -> SyntheticAccessorLowering(context).lower(file) },
|
||||||
|
name = "SyntheticAccessor",
|
||||||
|
description = "Introduce synthetic accessors",
|
||||||
|
prerequisite = setOf(ObjectClassPhase)
|
||||||
|
)
|
||||||
|
|
||||||
|
private val BridgePhase = makeJvmPhase(
|
||||||
|
{ context, file -> BridgeLowering(context).lower(file) },
|
||||||
|
name = "Bridge",
|
||||||
|
description = "Generate bridges"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val JvmOverloadsAnnotationPhase = makeJvmPhase(
|
||||||
|
{ context, file -> JvmOverloadsAnnotationLowering(context).lower(file) },
|
||||||
|
name = "JvmOverloadsAnnotation",
|
||||||
|
description = "Handle JvmOverloads annotations"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val JvmStaticAnnotationPhase = makeJvmPhase(
|
||||||
|
{ context, file -> JvmStaticAnnotationLowering(context).lower(file) },
|
||||||
|
name = "JvmStaticAnnotation",
|
||||||
|
description = "Handle JvmStatic annotations"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val StaticDefaultFunctionPhase = makeJvmPhase(
|
||||||
|
{ _, file -> StaticDefaultFunctionLowering().lower(file) },
|
||||||
|
name = "StaticDefaultFunction",
|
||||||
|
description = "Generate static functions for default parameters"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val TailrecPhase = makeJvmPhase(
|
||||||
|
{ context, file -> TailrecLowering(context).lower(file) },
|
||||||
|
name = "Tailrec",
|
||||||
|
description = "Handle tailrec calls"
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
private val ToArrayPhase = makeJvmPhase(
|
||||||
|
{ context, file -> ToArrayLowering(context).lower(file) },
|
||||||
|
name = "ToArray",
|
||||||
|
description = "Handle toArray functions"
|
||||||
|
)
|
||||||
|
|
||||||
|
object IrFileEndPhase : CompilerPhase<BackendContext, IrFile> {
|
||||||
|
override val name = "IrFileEnd"
|
||||||
|
override val description = "State at end of IrFile lowering"
|
||||||
|
override val prerequisite = emptySet()
|
||||||
|
override fun invoke(context: BackendContext, input: IrFile) = input
|
||||||
|
}
|
||||||
|
|
||||||
|
val jvmPhases = listOf(
|
||||||
|
IrFileStartPhase,
|
||||||
|
|
||||||
|
JvmCoercionToUnitPhase,
|
||||||
|
FileClassPhase,
|
||||||
|
KCallableNamePropertyPhase,
|
||||||
|
|
||||||
|
LateinitPhase,
|
||||||
|
|
||||||
|
MoveCompanionObjectFieldsPhase,
|
||||||
|
ConstAndJvmFieldPropertiesPhase,
|
||||||
|
PropertiesPhase,
|
||||||
|
AnnotationPhase,
|
||||||
|
|
||||||
|
DefaultArgumentStubPhase,
|
||||||
|
|
||||||
|
InterfacePhase,
|
||||||
|
InterfaceDelegationPhase,
|
||||||
|
SharedVariablesPhase,
|
||||||
|
|
||||||
|
makePatchParentsPhase(1),
|
||||||
|
|
||||||
|
LocalDeclarationsPhase,
|
||||||
|
CallableReferencePhase,
|
||||||
|
FunctionNVarargInvokePhase,
|
||||||
|
|
||||||
|
InnerClassesPhase,
|
||||||
|
InnerClassConstructorCallsPhase,
|
||||||
|
|
||||||
|
makePatchParentsPhase(2),
|
||||||
|
|
||||||
|
EnumClassPhase,
|
||||||
|
ObjectClassPhase,
|
||||||
|
InitializersPhase,
|
||||||
|
SingletonReferencesPhase,
|
||||||
|
SyntheticAccessorPhase,
|
||||||
|
BridgePhase,
|
||||||
|
JvmOverloadsAnnotationPhase,
|
||||||
|
JvmStaticAnnotationPhase,
|
||||||
|
StaticDefaultFunctionPhase,
|
||||||
|
|
||||||
|
TailrecPhase,
|
||||||
|
ToArrayPhase,
|
||||||
|
|
||||||
|
makePatchParentsPhase(3),
|
||||||
|
|
||||||
|
IrFileEndPhase
|
||||||
|
)
|
||||||
@@ -0,0 +1,19 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
|
||||||
|
* that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.jvm
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.DefaultIrPhaseRunner
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
|
import org.jetbrains.kotlin.ir.declarations.name
|
||||||
|
|
||||||
|
object JvmPhaseRunner : DefaultIrPhaseRunner<JvmBackendContext, IrFile>() {
|
||||||
|
override val startPhaseMarker = IrFileStartPhase
|
||||||
|
override val endPhaseMarker = IrFileEndPhase
|
||||||
|
|
||||||
|
override fun phases(context: JvmBackendContext) = context.phases
|
||||||
|
override fun elementName(input: IrFile) = input.name
|
||||||
|
override fun configuration(context: JvmBackendContext) = context.state.configuration
|
||||||
|
}
|
||||||
-6
@@ -12,12 +12,6 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
import org.jetbrains.kotlin.ir.declarations.IrConstructor
|
||||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||||
|
|
||||||
val AnnotationPhase = makePhase(
|
|
||||||
::AnnotationLowering,
|
|
||||||
name = "Annotation",
|
|
||||||
description = "Remove constructors from annotation classes"
|
|
||||||
)
|
|
||||||
|
|
||||||
class AnnotationLowering() : ClassLoweringPass {
|
class AnnotationLowering() : ClassLoweringPass {
|
||||||
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
||||||
|
|
||||||
|
|||||||
@@ -60,12 +60,6 @@ import org.jetbrains.org.objectweb.asm.Opcodes.*
|
|||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
import org.jetbrains.org.objectweb.asm.commons.Method
|
import org.jetbrains.org.objectweb.asm.commons.Method
|
||||||
|
|
||||||
val BridgePhase = makePhase(
|
|
||||||
::BridgeLowering,
|
|
||||||
name = "Bridge",
|
|
||||||
description = "Generate bridges"
|
|
||||||
)
|
|
||||||
|
|
||||||
class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||||
|
|
||||||
private val state = context.state
|
private val state = context.state
|
||||||
|
|||||||
-6
@@ -60,12 +60,6 @@ import org.jetbrains.kotlin.types.Variance
|
|||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
val CallableReferencePhase = makePhase(
|
|
||||||
::CallableReferenceLowering,
|
|
||||||
name = "CallableReference",
|
|
||||||
description = "Handle callable references"
|
|
||||||
)
|
|
||||||
|
|
||||||
//Hack implementation to support CR java types in lower
|
//Hack implementation to support CR java types in lower
|
||||||
class CrIrType(val type: Type) : IrType {
|
class CrIrType(val type: Type) : IrType {
|
||||||
override val annotations = emptyList()
|
override val annotations = emptyList()
|
||||||
|
|||||||
-6
@@ -22,12 +22,6 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|||||||
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
import org.jetbrains.kotlin.synthetic.SyntheticJavaPropertyDescriptor
|
||||||
|
|
||||||
val ConstAndJvmFieldPropertiesPhase = makePhase(
|
|
||||||
::ConstAndJvmFieldPropertiesLowering,
|
|
||||||
name = "ConstAndJvmFieldProperties",
|
|
||||||
description = "Substitute calls to const and Jvm>Field properties with const/field access"
|
|
||||||
)
|
|
||||||
|
|
||||||
class ConstAndJvmFieldPropertiesLowering(val context: CommonBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
|
class ConstAndJvmFieldPropertiesLowering(val context: CommonBackendContext) : IrElementTransformerVoid(), FileLoweringPass {
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.transformChildrenVoid(this)
|
irFile.transformChildrenVoid(this)
|
||||||
|
|||||||
-6
@@ -33,12 +33,6 @@ import org.jetbrains.kotlin.types.*
|
|||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
val EnumClassPhase = makePhase(
|
|
||||||
::EnumClassLowering,
|
|
||||||
name = "EnumClass",
|
|
||||||
description = "Handle enum classes"
|
|
||||||
)
|
|
||||||
|
|
||||||
class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
class EnumClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||||
override fun lower(irClass: IrClass) {
|
override fun lower(irClass: IrClass) {
|
||||||
if (!irClass.isEnumClass) return
|
if (!irClass.isEnumClass) return
|
||||||
|
|||||||
-6
@@ -34,12 +34,6 @@ import org.jetbrains.kotlin.psi2ir.PsiSourceManager
|
|||||||
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
import org.jetbrains.kotlin.resolve.source.KotlinSourceElement
|
||||||
import java.util.*
|
import java.util.*
|
||||||
|
|
||||||
val FileClassPhase = makePhase(
|
|
||||||
::FileClassLowering,
|
|
||||||
name = "FileClass",
|
|
||||||
description = "Put file level function and property declaration into a class"
|
|
||||||
)
|
|
||||||
|
|
||||||
class FileClassLowering(val context: JvmBackendContext) : FileLoweringPass {
|
class FileClassLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
val classes = ArrayList<IrClass>()
|
val classes = ArrayList<IrClass>()
|
||||||
|
|||||||
-6
@@ -30,12 +30,6 @@ import org.jetbrains.kotlin.ir.util.findDeclaration
|
|||||||
import org.jetbrains.kotlin.ir.util.isSubclassOf
|
import org.jetbrains.kotlin.ir.util.isSubclassOf
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
val FunctionNVarargInvokePhase = makePhase(
|
|
||||||
::FunctionNVarargInvokeLowering,
|
|
||||||
name = "FunctionNVarargInvoke",
|
|
||||||
description = "Handle invoke functions with large number of arguments"
|
|
||||||
)
|
|
||||||
|
|
||||||
class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : ClassLoweringPass {
|
class FunctionNVarargInvokeLowering(var context: JvmBackendContext) : ClassLoweringPass {
|
||||||
|
|
||||||
override fun lower(irClass: IrClass) {
|
override fun lower(irClass: IrClass) {
|
||||||
|
|||||||
-6
@@ -29,12 +29,6 @@ import org.jetbrains.kotlin.ir.util.createParameterDeclarations
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
|
||||||
val InterfaceDelegationPhase = makePhase(
|
|
||||||
::InterfaceDelegationLowering,
|
|
||||||
name = "InterfaceDelegation",
|
|
||||||
description = "Delegate calls to interface members with default implementations to DefaultImpls"
|
|
||||||
)
|
|
||||||
|
|
||||||
class InterfaceDelegationLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
|
class InterfaceDelegationLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||||
|
|
||||||
val state: GenerationState = context.state
|
val state: GenerationState = context.state
|
||||||
|
|||||||
-6
@@ -28,12 +28,6 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
|
|
||||||
val InterfacePhase = makePhase(
|
|
||||||
::InterfaceLowering,
|
|
||||||
name = "Interface",
|
|
||||||
description = "Move default implementations of interface members to DefaultImpls class"
|
|
||||||
)
|
|
||||||
|
|
||||||
class InterfaceLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
|
class InterfaceLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), ClassLoweringPass {
|
||||||
|
|
||||||
val state = context.state
|
val state = context.state
|
||||||
|
|||||||
-6
@@ -17,12 +17,6 @@ import org.jetbrains.kotlin.ir.util.TypeTranslator
|
|||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
import org.jetbrains.kotlin.psi2ir.transformations.InsertImplicitCasts
|
import org.jetbrains.kotlin.psi2ir.transformations.InsertImplicitCasts
|
||||||
|
|
||||||
val JvmCoercionToUnitPhase = makePhase(
|
|
||||||
::JvmCoercionToUnitPatcher,
|
|
||||||
name = "JvmCoercionToUnit",
|
|
||||||
description = "Insert conversions to unit after IrCalls where needed"
|
|
||||||
)
|
|
||||||
|
|
||||||
class JvmCoercionToUnitPatcher(val context: JvmBackendContext) :
|
class JvmCoercionToUnitPatcher(val context: JvmBackendContext) :
|
||||||
InsertImplicitCasts(
|
InsertImplicitCasts(
|
||||||
context.builtIns, context.irBuiltIns,
|
context.builtIns, context.irBuiltIns,
|
||||||
|
|||||||
-6
@@ -35,12 +35,6 @@ import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols
|
|||||||
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue
|
||||||
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
import org.jetbrains.kotlin.resolve.jvm.annotations.findJvmOverloadsAnnotation
|
||||||
|
|
||||||
val JvmOverloadsAnnotationPhase = makePhase(
|
|
||||||
::JvmOverloadsAnnotationLowering,
|
|
||||||
name = "JvmOverloadsAnnotation",
|
|
||||||
description = "Handle JvmOverloads annotations"
|
|
||||||
)
|
|
||||||
|
|
||||||
class JvmOverloadsAnnotationLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
class JvmOverloadsAnnotationLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||||
|
|
||||||
override fun lower(irClass: IrClass) {
|
override fun lower(irClass: IrClass) {
|
||||||
|
|||||||
-6
@@ -36,12 +36,6 @@ import org.jetbrains.kotlin.name.Name
|
|||||||
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.resolve.annotations.JVM_STATIC_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||||
|
|
||||||
val JvmStaticAnnotationPhase = makePhase(
|
|
||||||
::JvmStaticAnnotationLowering,
|
|
||||||
name = "JvmStaticAnnotation",
|
|
||||||
description = "Handle JvmStatic annotations"
|
|
||||||
)
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* For @JvmStatic functions within companion objects of classes, we synthesize proxy static functions that redirect
|
* For @JvmStatic functions within companion objects of classes, we synthesize proxy static functions that redirect
|
||||||
* to the actual implementation.
|
* to the actual implementation.
|
||||||
|
|||||||
-6
@@ -33,12 +33,6 @@ import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|||||||
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
import org.jetbrains.kotlin.load.java.JvmAbi.JVM_FIELD_ANNOTATION_FQ_NAME
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
|
|
||||||
val MoveCompanionObjectFieldsPhase = makePhase(
|
|
||||||
::MoveCompanionObjectFieldsLowering,
|
|
||||||
name = "MoveCompanionObjectFields",
|
|
||||||
description = "Move companion object fields to static fields of companion's owner"
|
|
||||||
)
|
|
||||||
|
|
||||||
class MoveCompanionObjectFieldsLowering(val context: CommonBackendContext) : ClassLoweringPass {
|
class MoveCompanionObjectFieldsLowering(val context: CommonBackendContext) : ClassLoweringPass {
|
||||||
override fun lower(irClass: IrClass) {
|
override fun lower(irClass: IrClass) {
|
||||||
val fieldReplacementMap = mutableMapOf<IrFieldSymbol, IrFieldSymbol>()
|
val fieldReplacementMap = mutableMapOf<IrFieldSymbol, IrFieldSymbol>()
|
||||||
|
|||||||
-6
@@ -25,12 +25,6 @@ import org.jetbrains.kotlin.ir.types.IrType
|
|||||||
import org.jetbrains.kotlin.ir.util.defaultType
|
import org.jetbrains.kotlin.ir.util.defaultType
|
||||||
import org.jetbrains.kotlin.ir.util.isObject
|
import org.jetbrains.kotlin.ir.util.isObject
|
||||||
|
|
||||||
val ObjectClassPhase = makePhase(
|
|
||||||
::ObjectClassLowering,
|
|
||||||
name = "ObjectClass",
|
|
||||||
description = "Handle object classes"
|
|
||||||
)
|
|
||||||
|
|
||||||
class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||||
|
|
||||||
private var pendingTransformations = mutableListOf<Function0<Unit>>()
|
private var pendingTransformations = mutableListOf<Function0<Unit>>()
|
||||||
|
|||||||
-6
@@ -16,12 +16,6 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
|
||||||
val SingletonReferencesPhase = makePhase(
|
|
||||||
::SingletonReferencesLowering,
|
|
||||||
name = "SingletonReferences",
|
|
||||||
description = "Handle singleton references"
|
|
||||||
)
|
|
||||||
|
|
||||||
class SingletonReferencesLowering(val context: JvmBackendContext) : BodyLoweringPass, IrElementTransformerVoid() {
|
class SingletonReferencesLowering(val context: JvmBackendContext) : BodyLoweringPass, IrElementTransformerVoid() {
|
||||||
override fun lower(irBody: IrBody) {
|
override fun lower(irBody: IrBody) {
|
||||||
irBody.transformChildrenVoid(this)
|
irBody.transformChildrenVoid(this)
|
||||||
|
|||||||
-6
@@ -27,12 +27,6 @@ import org.jetbrains.kotlin.ir.declarations.IrClass
|
|||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
|
||||||
val StaticDefaultFunctionPhase = makePhase(
|
|
||||||
::StaticDefaultFunctionLowering,
|
|
||||||
name = "StaticDefaultFunction",
|
|
||||||
description = "Generate static functions for default parameters"
|
|
||||||
)
|
|
||||||
|
|
||||||
class StaticDefaultFunctionLowering() : IrElementTransformerVoid(), ClassLoweringPass {
|
class StaticDefaultFunctionLowering() : IrElementTransformerVoid(), ClassLoweringPass {
|
||||||
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
constructor(@Suppress("UNUSED_PARAMETER") context: BackendContext) : this()
|
||||||
|
|
||||||
|
|||||||
-7
@@ -37,13 +37,6 @@ import org.jetbrains.kotlin.load.java.JvmAbi
|
|||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
import org.jetbrains.kotlin.resolve.DescriptorUtils
|
||||||
|
|
||||||
val SyntheticAccessorPhase = makePhase(
|
|
||||||
::SyntheticAccessorLowering,
|
|
||||||
name = "SyntheticAccessor",
|
|
||||||
description = "Introduce synthetic accessors",
|
|
||||||
prerequisite = setOf(ObjectClassPhase)
|
|
||||||
)
|
|
||||||
|
|
||||||
class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
class SyntheticAccessorLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
||||||
private val pendingTransformations = mutableListOf<Function0<Unit>>()
|
private val pendingTransformations = mutableListOf<Function0<Unit>>()
|
||||||
private val inlinedLambdasCollector = InlinedLambdasCollector()
|
private val inlinedLambdasCollector = InlinedLambdasCollector()
|
||||||
|
|||||||
@@ -43,12 +43,6 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.builtIns
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny
|
import org.jetbrains.kotlin.resolve.descriptorUtil.getAllSuperclassesWithoutAny
|
||||||
import org.jetbrains.kotlin.types.Variance
|
import org.jetbrains.kotlin.types.Variance
|
||||||
|
|
||||||
val ToArrayPhase = makePhase(
|
|
||||||
::ToArrayLowering,
|
|
||||||
name = "ToArray",
|
|
||||||
description = "Handle toArray functions"
|
|
||||||
)
|
|
||||||
|
|
||||||
class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPass {
|
class ToArrayLowering(private val context: JvmBackendContext) : ClassLoweringPass {
|
||||||
|
|
||||||
override fun lower(irClass: IrClass) {
|
override fun lower(irClass: IrClass) {
|
||||||
|
|||||||
Reference in New Issue
Block a user