JVM IR: Lower calls to the emptyArray intrinsic in VarargLowering

There are two array intrinsics which are handled in the inliner on the
JVM backend: arrayOf and emptyArray. In the IR backend we are already
lowering arrayOf as part of VarargLowering and this commit adds support
for lowering emptyArray as well.
This commit is contained in:
Steven Schäfer
2020-01-06 13:58:21 +01:00
committed by Alexander Udalov
parent 1b1dff9191
commit bd74e976c9
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
val varargPhase = makeIrFilePhase( val varargPhase = makeIrFilePhase(
::VarargLowering, ::VarargLowering,
name = "VarargLowering", name = "VarargLowering",
description = "Replace varargs with array arguments and lower arrayOf calls", description = "Replace varargs with array arguments and lower arrayOf and emptyArray calls",
prerequisite = setOf(polymorphicSignaturePhase) prerequisite = setOf(polymorphicSignaturePhase)
) )
@@ -62,9 +62,16 @@ private class VarargLowering(val context: JvmBackendContext) : FileLoweringPass,
} }
} }
// Lower `arrayOf` calls. When `isArrayOf` returns true we know that the function has exactly one return when {
// vararg parameter. Meanwhile, the code above ensures that the corresponding argument is not null. // Lower `arrayOf` calls. When `isArrayOf` returns true we know that the function has exactly one
return if (function.isArrayOf) expression.getValueArgument(0)!! else expression // vararg parameter. Meanwhile, the code above ensures that the corresponding argument is not null.
function.isArrayOf ->
expression.getValueArgument(0)!!
function.isEmptyArray ->
createBuilder(expression.startOffset, expression.endOffset).irArrayOf(expression.type)
else ->
expression
}
} }
override fun visitVararg(expression: IrVararg): IrExpression = override fun visitVararg(expression: IrVararg): IrExpression =
@@ -94,9 +101,12 @@ private class VarargLowering(val context: JvmBackendContext) : FileLoweringPass,
private fun createBuilder(startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET) = private fun createBuilder(startOffset: Int = UNDEFINED_OFFSET, endOffset: Int = UNDEFINED_OFFSET) =
context.createJvmIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset) context.createJvmIrBuilder(currentScope!!.scope.scopeOwnerSymbol, startOffset, endOffset)
private val IrFunctionSymbol.isArrayOf private val IrFunctionSymbol.isArrayOf: Boolean
get() = this == context.ir.symbols.arrayOf || owner.isPrimitiveArrayOf get() = this == context.ir.symbols.arrayOf || owner.isPrimitiveArrayOf
private val IrFunctionSymbol.isEmptyArray: Boolean
get() = owner.name.asString() == "emptyArray" && (owner.parent as? IrPackageFragment)?.fqName == KotlinBuiltIns.BUILT_INS_PACKAGE_FQ_NAME
companion object { companion object {
private val PRIMITIVE_ARRAY_OF_NAMES: Set<String> = private val PRIMITIVE_ARRAY_OF_NAMES: Set<String> =
(PrimitiveType.values().map { type -> type.name } + UnsignedType.values().map { type -> type.typeName.asString() }) (PrimitiveType.values().map { type -> type.name } + UnsignedType.values().map { type -> type.typeName.asString() })