Used common special arrays constructors lowering

This commit is contained in:
Igor Chevdar
2019-08-12 17:40:56 +03:00
parent 9e149b6d91
commit 39d4a9b25d
7 changed files with 9 additions and 61 deletions
@@ -73,6 +73,12 @@ internal val lowerBeforeInlinePhase = makeKonanModuleLoweringPhase(
description = "Special operations processing before inlining" description = "Special operations processing before inlining"
) )
internal val arrayConstructorPhase = makeKonanModuleLoweringPhase(
::ArrayConstructorLowering,
name = "ArrayConstructor",
description = "Transform `Array(size) { index -> value }` into a loop"
)
internal val inlinePhase = namedIrModulePhase( internal val inlinePhase = namedIrModulePhase(
lower = object : SameTypeCompilerPhase<Context, IrModuleFragment> { lower = object : SameTypeCompilerPhase<Context, IrModuleFragment> {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<IrModuleFragment>, context: Context, input: IrModuleFragment): IrModuleFragment { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<IrModuleFragment>, context: Context, input: IrModuleFragment): IrModuleFragment {
@@ -82,7 +88,7 @@ internal val inlinePhase = namedIrModulePhase(
}, },
name = "Inline", name = "Inline",
description = "Functions inlining", description = "Functions inlining",
prerequisite = setOf(lowerBeforeInlinePhase), prerequisite = setOf(lowerBeforeInlinePhase, arrayConstructorPhase),
nlevels = 0, nlevels = 0,
actions = modulePhaseActions actions = modulePhaseActions
) )
@@ -240,6 +240,7 @@ internal val allLoweringsPhase = namedIrModulePhase(
lower = removeExpectDeclarationsPhase then lower = removeExpectDeclarationsPhase then
lowerBeforeInlinePhase then lowerBeforeInlinePhase then
provisionalFunctionExpressionPhase then provisionalFunctionExpressionPhase then
arrayConstructorPhase then
inlinePhase then inlinePhase then
lowerAfterInlinePhase then lowerAfterInlinePhase then
interopPart1Phase then interopPart1Phase then
@@ -19,7 +19,6 @@ import org.jetbrains.kotlin.descriptors.ValueDescriptor
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irReturn import org.jetbrains.kotlin.ir.builders.irReturn
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
@@ -32,7 +31,6 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
internal class FunctionInlining(val context: Context) : IrElementTransformerVoidWithContext() { internal class FunctionInlining(val context: Context) : IrElementTransformerVoidWithContext() {
@@ -82,11 +80,7 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
} }
} }
private val inlineConstructor = FqName("kotlin.native.internal.InlineConstructor") private val IrFunction.needsInlining get() = this.isInline && !this.isExternal
private val IrFunction.isInlineConstructor get() = annotations.hasAnnotation(inlineConstructor)
private val IrFunction.needsInlining get() = isInlineConstructor || (this.isInline && !this.isExternal)
private inner class Inliner(val callSite: IrFunctionAccessExpression, private inner class Inliner(val callSite: IrFunctionAccessExpression,
val callee: IrFunction, val callee: IrFunction,
@@ -132,46 +126,12 @@ internal class FunctionInlining(val context: Context) : IrElementTransformerVoid
val statements = (copiedCallee.body as IrBlockBody).statements val statements = (copiedCallee.body as IrBlockBody).statements
val irReturnableBlockSymbol = IrReturnableBlockSymbolImpl(copiedCallee.descriptor.original) val irReturnableBlockSymbol = IrReturnableBlockSymbolImpl(copiedCallee.descriptor.original)
val startOffset = callee.startOffset
val endOffset = callee.endOffset val endOffset = callee.endOffset
/* creates irBuilder appending to the end of the given returnable block: thus why we initialize /* creates irBuilder appending to the end of the given returnable block: thus why we initialize
* irBuilder with (..., endOffset, endOffset). * irBuilder with (..., endOffset, endOffset).
*/ */
val irBuilder = context.createIrBuilder(irReturnableBlockSymbol, endOffset, endOffset) val irBuilder = context.createIrBuilder(irReturnableBlockSymbol, endOffset, endOffset)
if (callee.isInlineConstructor) {
// Copier sets parent to be the current function but
// constructor's parent cannot be a function.
val constructedClass = callee.parentAsClass
copiedCallee.parent = constructedClass
val delegatingConstructorCall = statements[0] as IrDelegatingConstructorCall
// TODO: Try use type parameters from callee.
irBuilder.run {
val constructorCall = IrConstructorCallImpl(
startOffset, endOffset,
callSite.type,
delegatingConstructorCall.symbol, delegatingConstructorCall.descriptor,
constructedClass.typeParameters.size, 0,
delegatingConstructorCall.symbol.owner.valueParameters.size
).apply {
delegatingConstructorCall.symbol.owner.valueParameters.forEach {
putValueArgument(it.index, delegatingConstructorCall.getValueArgument(it.index))
}
constructedClass.typeParameters.forEach {
putTypeArgument(it.index, delegatingConstructorCall.getTypeArgument(it.index))
}
}
val oldThis = constructedClass.thisReceiver!!
val newThis = currentScope.scope.createTemporaryVariableWithWrappedDescriptor(
irExpression = constructorCall,
nameHint = constructedClass.fqNameForIrSerialization.toString() + ".this"
)
statements[0] = newThis
substituteMap[oldThis] = irGet(newThis)
statements.add(irReturn(irGet(newThis)))
}
}
val sourceFile = callee.file val sourceFile = callee.file
val transformer = ParameterSubstitutor() val transformer = ParameterSubstitutor()
-2
View File
@@ -7,7 +7,6 @@ package kotlin
import kotlin.native.internal.ExportForCompiler import kotlin.native.internal.ExportForCompiler
import kotlin.native.internal.ExportTypeInfo import kotlin.native.internal.ExportTypeInfo
import kotlin.native.internal.InlineConstructor
import kotlin.native.internal.PointsTo import kotlin.native.internal.PointsTo
/** /**
@@ -26,7 +25,6 @@ public final class Array<T> {
* The function [init] is called for each array element sequentially starting from the first one. * The function [init] is called for each array element sequentially starting from the first one.
* It should return the value for an array element given its index. * It should return the value for an array element given its index.
*/ */
@InlineConstructor
@Suppress("TYPE_PARAMETER_AS_REIFIED") @Suppress("TYPE_PARAMETER_AS_REIFIED")
public constructor(size: Int, init: (Int) -> T): this(size) { public constructor(size: Int, init: (Int) -> T): this(size) {
var index = 0 var index = 0
-9
View File
@@ -10,7 +10,6 @@ package kotlin
import kotlin.internal.PureReifiable import kotlin.internal.PureReifiable
import kotlin.native.internal.ExportTypeInfo import kotlin.native.internal.ExportTypeInfo
import kotlin.native.internal.InlineConstructor
import kotlin.native.internal.IntrinsicType import kotlin.native.internal.IntrinsicType
import kotlin.native.internal.TypedIntrinsic import kotlin.native.internal.TypedIntrinsic
@@ -30,7 +29,6 @@ public final class ByteArray {
* The function [init] is called for each array element sequentially starting from the first one. * The function [init] is called for each array element sequentially starting from the first one.
* It should return the value for an array element given its index. * It should return the value for an array element given its index.
*/ */
@InlineConstructor
public constructor(size: Int, init: (Int) -> Byte): this(size) { public constructor(size: Int, init: (Int) -> Byte): this(size) {
for (i in 0..size - 1) { for (i in 0..size - 1) {
this[i] = init(i) this[i] = init(i)
@@ -94,7 +92,6 @@ public final class CharArray {
* The function [init] is called for each array element sequentially starting from the first one. * The function [init] is called for each array element sequentially starting from the first one.
* It should return the value for an array element given its index. * It should return the value for an array element given its index.
*/ */
@InlineConstructor
public constructor(size: Int, init: (Int) -> Char): this(size) { public constructor(size: Int, init: (Int) -> Char): this(size) {
for (i in 0..size - 1) { for (i in 0..size - 1) {
this[i] = init(i) this[i] = init(i)
@@ -159,7 +156,6 @@ public final class ShortArray {
* The function [init] is called for each array element sequentially starting from the first one. * The function [init] is called for each array element sequentially starting from the first one.
* It should return the value for an array element given its index. * It should return the value for an array element given its index.
*/ */
@InlineConstructor
public constructor(size: Int, init: (Int) -> Short): this(size) { public constructor(size: Int, init: (Int) -> Short): this(size) {
for (i in 0..size - 1) { for (i in 0..size - 1) {
this[i] = init(i) this[i] = init(i)
@@ -224,7 +220,6 @@ public final class IntArray {
* The function [init] is called for each array element sequentially starting from the first one. * The function [init] is called for each array element sequentially starting from the first one.
* It should return the value for an array element given its index. * It should return the value for an array element given its index.
*/ */
@InlineConstructor
public constructor(size: Int, init: (Int) -> Int): this(size) { public constructor(size: Int, init: (Int) -> Int): this(size) {
for (i in 0..size - 1) { for (i in 0..size - 1) {
this[i] = init(i) this[i] = init(i)
@@ -289,7 +284,6 @@ public final class LongArray {
* The function [init] is called for each array element sequentially starting from the first one. * The function [init] is called for each array element sequentially starting from the first one.
* It should return the value for an array element given its index. * It should return the value for an array element given its index.
*/ */
@InlineConstructor
public constructor(size: Int, init: (Int) -> Long): this(size) { public constructor(size: Int, init: (Int) -> Long): this(size) {
for (i in 0..size - 1) { for (i in 0..size - 1) {
this[i] = init(i) this[i] = init(i)
@@ -354,7 +348,6 @@ public final class FloatArray {
* The function [init] is called for each array element sequentially starting from the first one. * The function [init] is called for each array element sequentially starting from the first one.
* It should return the value for an array element given its index. * It should return the value for an array element given its index.
*/ */
@InlineConstructor
public constructor(size: Int, init: (Int) -> Float): this(size) { public constructor(size: Int, init: (Int) -> Float): this(size) {
for (i in 0..size - 1) { for (i in 0..size - 1) {
this[i] = init(i) this[i] = init(i)
@@ -415,7 +408,6 @@ public final class DoubleArray {
* The function [init] is called for each array element sequentially starting from the first one. * The function [init] is called for each array element sequentially starting from the first one.
* It should return the value for an array element given its index. * It should return the value for an array element given its index.
*/ */
@InlineConstructor
public constructor(size: Int, init: (Int) -> Double): this(size) { public constructor(size: Int, init: (Int) -> Double): this(size) {
for (i in 0..size - 1) { for (i in 0..size - 1) {
this[i] = init(i) this[i] = init(i)
@@ -476,7 +468,6 @@ public final class BooleanArray {
* The function [init] is called for each array element sequentially starting from the first one. * The function [init] is called for each array element sequentially starting from the first one.
* It should return the value for an array element given its index. * It should return the value for an array element given its index.
*/ */
@InlineConstructor
public constructor(size: Int, init: (Int) -> Boolean): this(size) { public constructor(size: Int, init: (Int) -> Boolean): this(size) {
for (i in 0..size - 1) { for (i in 0..size - 1) {
this[i] = init(i) this[i] = init(i)
@@ -5,7 +5,6 @@
package kotlin.collections package kotlin.collections
import kotlin.native.internal.InlineConstructor
import kotlin.internal.PureReifiable import kotlin.internal.PureReifiable
/** Returns the array if it's not `null`, or an empty array otherwise. */ /** Returns the array if it's not `null`, or an empty array otherwise. */
@@ -40,13 +40,6 @@ internal annotation class Intrinsic
@Retention(AnnotationRetention.BINARY) @Retention(AnnotationRetention.BINARY)
public annotation class ExportForCompiler public annotation class ExportForCompiler
/**
* Annotated constructor will be inlined.
*/
@Target(AnnotationTarget.CONSTRUCTOR)
@Retention(AnnotationRetention.BINARY)
internal annotation class InlineConstructor
/** /**
* Class is frozen by default. Also this annotation is (ab)used for marking objects * Class is frozen by default. Also this annotation is (ab)used for marking objects
* where mutability checks are not needed, and they are shared, such as atomics. * where mutability checks are not needed, and they are shared, such as atomics.