JVM IR: inherit some lowerings from ClassLoweringPass
This slightly simplifies code, but has no other immediate benefits. In the future though, we may end up optimizing all ClassLoweringPass JVM IR phases by making them traverse only one list of all classes in the module, instead of traversing the whole IR tree each time.
This commit is contained in:
committed by
Space Team
parent
073df585c4
commit
3246b0a6bd
+6
-13
@@ -5,16 +5,12 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
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.declarations.IrFile
|
|
||||||
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
import org.jetbrains.kotlin.ir.util.isAnnotationClass
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
|
||||||
|
|
||||||
internal val annotationPhase = makeIrFilePhase<JvmBackendContext>(
|
internal val annotationPhase = makeIrFilePhase<JvmBackendContext>(
|
||||||
{ AnnotationLowering() },
|
{ AnnotationLowering() },
|
||||||
@@ -22,13 +18,10 @@ internal val annotationPhase = makeIrFilePhase<JvmBackendContext>(
|
|||||||
description = "Remove constructors of annotation classes"
|
description = "Remove constructors of annotation classes"
|
||||||
)
|
)
|
||||||
|
|
||||||
private class AnnotationLowering : FileLoweringPass, IrElementTransformerVoid() {
|
private class AnnotationLowering : ClassLoweringPass {
|
||||||
override fun lower(irFile: IrFile) = irFile.transformChildrenVoid(this)
|
override fun lower(irClass: IrClass) {
|
||||||
|
if (irClass.isAnnotationClass) {
|
||||||
override fun visitClass(declaration: IrClass): IrStatement =
|
irClass.declarations.removeIf { it is IrConstructor }
|
||||||
declaration.transformPostfix {
|
|
||||||
if (isAnnotationClass) {
|
|
||||||
declarations.removeIf { it is IrConstructor }
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+10
-20
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.lower.SpecialMethodWithDefaultInfo
|
import org.jetbrains.kotlin.backend.common.lower.SpecialMethodWithDefaultInfo
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.lower.irNot
|
import org.jetbrains.kotlin.backend.common.lower.irNot
|
||||||
@@ -18,7 +18,6 @@ import org.jetbrains.kotlin.backend.jvm.ir.*
|
|||||||
import org.jetbrains.kotlin.codegen.AsmUtil
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
import org.jetbrains.kotlin.ir.builders.declarations.addFunction
|
||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
@@ -30,7 +29,6 @@ import org.jetbrains.kotlin.ir.types.isNullable
|
|||||||
import org.jetbrains.kotlin.ir.types.isPrimitiveType
|
import org.jetbrains.kotlin.ir.types.isPrimitiveType
|
||||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
|
||||||
import org.jetbrains.kotlin.name.Name
|
import org.jetbrains.kotlin.name.Name
|
||||||
import org.jetbrains.kotlin.utils.SmartList
|
import org.jetbrains.kotlin.utils.SmartList
|
||||||
import org.jetbrains.org.objectweb.asm.Type
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
@@ -118,7 +116,7 @@ internal val bridgePhase = makeIrFilePhase(
|
|||||||
prerequisite = setOf(jvmValueClassPhase, inheritedDefaultMethodsOnClassesPhase)
|
prerequisite = setOf(jvmValueClassPhase, inheritedDefaultMethodsOnClassesPhase)
|
||||||
)
|
)
|
||||||
|
|
||||||
internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass, IrElementTransformerVoid() {
|
internal class BridgeLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||||
// Represents a synthetic bridge to `overridden` with a precomputed signature
|
// Represents a synthetic bridge to `overridden` with a precomputed signature
|
||||||
private class Bridge(
|
private class Bridge(
|
||||||
val overridden: IrSimpleFunction,
|
val overridden: IrSimpleFunction,
|
||||||
@@ -126,27 +124,21 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
|||||||
val overriddenSymbols: MutableList<IrSimpleFunctionSymbol> = mutableListOf()
|
val overriddenSymbols: MutableList<IrSimpleFunctionSymbol> = mutableListOf()
|
||||||
)
|
)
|
||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irClass: IrClass) {
|
||||||
irFile.transformChildrenVoid()
|
// Bridges in DefaultImpls classes are handled in InterfaceLowering.
|
||||||
}
|
if (irClass.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS || irClass.isAnnotationClass) return
|
||||||
|
|
||||||
override fun visitClass(declaration: IrClass): IrStatement {
|
val bridgeTargets = irClass.functions.filterTo(SmartList()) { it.isPotentialBridgeTarget() }
|
||||||
// Bridges in DefaultImpl classes are handled in InterfaceLowering.
|
if (bridgeTargets.isEmpty()) return
|
||||||
if (declaration.origin == JvmLoweredDeclarationOrigin.DEFAULT_IMPLS || declaration.isAnnotationClass)
|
|
||||||
return super.visitClass(declaration)
|
|
||||||
|
|
||||||
val bridgeTargets = declaration.functions.filterTo(SmartList()) { it.isPotentialBridgeTarget() }
|
bridgeTargets.forEach { createBridges(irClass, it) }
|
||||||
if (bridgeTargets.isEmpty())
|
|
||||||
return super.visitClass(declaration)
|
|
||||||
|
|
||||||
bridgeTargets.forEach { createBridges(declaration, it) }
|
if (irClass.isSingleFieldValueClass) {
|
||||||
|
|
||||||
if (declaration.isSingleFieldValueClass) {
|
|
||||||
// Inline class (implementing 'MutableCollection<T>', where T is Int or an inline class mapped to Int)
|
// Inline class (implementing 'MutableCollection<T>', where T is Int or an inline class mapped to Int)
|
||||||
// can contain a static replacement for a function 'remove', which forces value parameter boxing
|
// can contain a static replacement for a function 'remove', which forces value parameter boxing
|
||||||
// in order to avoid signature clash with 'remove(int)' method in 'java.util.List'.
|
// in order to avoid signature clash with 'remove(int)' method in 'java.util.List'.
|
||||||
// We should rewrite this static replacement as well ('remove' function itself is handled during special bridge processing).
|
// We should rewrite this static replacement as well ('remove' function itself is handled during special bridge processing).
|
||||||
val remove = declaration.functions.find {
|
val remove = irClass.functions.find {
|
||||||
val original = context.inlineClassReplacements.originalFunctionForStaticReplacement[it]
|
val original = context.inlineClassReplacements.originalFunctionForStaticReplacement[it]
|
||||||
original != null && context.defaultMethodSignatureMapper.shouldBoxSingleValueParameterForSpecialCaseOfRemove(original)
|
original != null && context.defaultMethodSignatureMapper.shouldBoxSingleValueParameterForSpecialCaseOfRemove(original)
|
||||||
}
|
}
|
||||||
@@ -156,8 +148,6 @@ internal class BridgeLowering(val context: JvmBackendContext) : FileLoweringPass
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return super.visitClass(declaration)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun IrSimpleFunction.isPotentialBridgeTarget(): Boolean {
|
private fun IrSimpleFunction.isPotentialBridgeTarget(): Boolean {
|
||||||
|
|||||||
+11
-10
@@ -28,7 +28,9 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
|||||||
import org.jetbrains.kotlin.ir.expressions.putArgument
|
import org.jetbrains.kotlin.ir.expressions.putArgument
|
||||||
import org.jetbrains.kotlin.ir.types.IrType
|
import org.jetbrains.kotlin.ir.types.IrType
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.*
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
|
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||||
|
|
||||||
internal val inheritedDefaultMethodsOnClassesPhase = makeIrFilePhase(
|
internal val inheritedDefaultMethodsOnClassesPhase = makeIrFilePhase(
|
||||||
::InheritedDefaultMethodsOnClassesLowering,
|
::InheritedDefaultMethodsOnClassesLowering,
|
||||||
@@ -123,25 +125,24 @@ internal val replaceDefaultImplsOverriddenSymbolsPhase = makeIrFilePhase(
|
|||||||
description = "Replace overridden symbols for methods inherited from interfaces to classes"
|
description = "Replace overridden symbols for methods inherited from interfaces to classes"
|
||||||
)
|
)
|
||||||
|
|
||||||
private class ReplaceDefaultImplsOverriddenSymbols(private val context: JvmBackendContext) : FileLoweringPass, IrElementVisitorVoid {
|
private class ReplaceDefaultImplsOverriddenSymbols(private val context: JvmBackendContext) : ClassLoweringPass {
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irClass: IrClass) {
|
||||||
irFile.acceptVoid(this)
|
for (declaration in irClass.declarations) {
|
||||||
}
|
if (declaration is IrSimpleFunction) {
|
||||||
|
visitSimpleFunction(declaration)
|
||||||
override fun visitElement(element: IrElement) {
|
}
|
||||||
element.acceptChildrenVoid(this)
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Functions introduced by InheritedDefaultMethodsOnClassesLowering may be inherited lower in the hierarchy.
|
// Functions introduced by InheritedDefaultMethodsOnClassesLowering may be inherited lower in the hierarchy.
|
||||||
// Here we use the same logic as the delegation itself (`getTargetForRedirection`) to determine
|
// Here we use the same logic as the delegation itself (`getTargetForRedirection`) to determine
|
||||||
// if the overridden symbol has been, or will be, replaced and patch it accordingly.
|
// if the overridden symbol has been, or will be, replaced and patch it accordingly.
|
||||||
override fun visitSimpleFunction(declaration: IrSimpleFunction) {
|
fun visitSimpleFunction(declaration: IrSimpleFunction) {
|
||||||
declaration.overriddenSymbols = declaration.overriddenSymbols.map { symbol ->
|
declaration.overriddenSymbols = declaration.overriddenSymbols.map { symbol ->
|
||||||
if (symbol.owner.findInterfaceImplementation(context.config.jvmDefaultMode) != null)
|
if (symbol.owner.findInterfaceImplementation(context.config.jvmDefaultMode) != null)
|
||||||
context.cachedDeclarations.getDefaultImplsRedirection(symbol.owner).symbol
|
context.cachedDeclarations.getDefaultImplsRedirection(symbol.owner).symbol
|
||||||
else symbol
|
else symbol
|
||||||
}
|
}
|
||||||
super.visitSimpleFunction(declaration)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+8
-16
@@ -5,15 +5,13 @@
|
|||||||
|
|
||||||
package org.jetbrains.kotlin.backend.jvm.lower
|
package org.jetbrains.kotlin.backend.jvm.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
|
||||||
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
|
||||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
|
||||||
import org.jetbrains.kotlin.config.LanguageFeature
|
import org.jetbrains.kotlin.config.LanguageFeature
|
||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||||
import org.jetbrains.kotlin.ir.IrStatement
|
|
||||||
import org.jetbrains.kotlin.ir.builders.irCall
|
import org.jetbrains.kotlin.ir.builders.irCall
|
||||||
import org.jetbrains.kotlin.ir.builders.irExprBody
|
import org.jetbrains.kotlin.ir.builders.irExprBody
|
||||||
import org.jetbrains.kotlin.ir.builders.irGetField
|
import org.jetbrains.kotlin.ir.builders.irGetField
|
||||||
@@ -31,23 +29,17 @@ internal val objectClassPhase = makeIrFilePhase(
|
|||||||
description = "Handle object classes"
|
description = "Handle object classes"
|
||||||
)
|
)
|
||||||
|
|
||||||
private class ObjectClassLowering(val context: JvmBackendContext) : IrElementTransformerVoidWithContext(), FileLoweringPass {
|
private class ObjectClassLowering(val context: JvmBackendContext) : ClassLoweringPass {
|
||||||
|
private val pendingTransformations = mutableListOf<Function0<Unit>>()
|
||||||
private var pendingTransformations = mutableListOf<Function0<Unit>>()
|
|
||||||
|
|
||||||
override fun lower(irFile: IrFile) {
|
override fun lower(irFile: IrFile) {
|
||||||
irFile.accept(this, null)
|
super.lower(irFile)
|
||||||
|
for (transformation in pendingTransformations) {
|
||||||
pendingTransformations.forEach { it() }
|
transformation.invoke()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitClassNew(declaration: IrClass): IrStatement {
|
override fun lower(irClass: IrClass) {
|
||||||
process(declaration)
|
|
||||||
return super.visitClassNew(declaration)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private fun process(irClass: IrClass) {
|
|
||||||
if (!irClass.isObject) return
|
if (!irClass.isObject) return
|
||||||
|
|
||||||
val publicInstanceField = context.cachedDeclarations.getFieldForObjectInstance(irClass)
|
val publicInstanceField = context.cachedDeclarations.getFieldForObjectInstance(irClass)
|
||||||
|
|||||||
Reference in New Issue
Block a user