Use annotation to distinct inline constructor
This commit is contained in:
committed by
KonstantinAnisimov
parent
31a24d4607
commit
ba1f3d502e
+4
-16
@@ -312,25 +312,13 @@ internal fun DeclarationDescriptor.getMemberScope(): MemberScope {
|
||||
// It is possible to declare "external inline fun",
|
||||
// but it doesn't have much sense for native,
|
||||
// since externals don't have IR bodies.
|
||||
|
||||
// Enforce inlining of some constructors
|
||||
private val mustInlineFunctions = setOf(
|
||||
"kotlin.DoubleArray.<init>",
|
||||
"kotlin.FloatArray.<init>",
|
||||
"kotlin.ByteArray.<init>",
|
||||
"kotlin.ShortArray.<init>",
|
||||
"kotlin.IntArray.<init>",
|
||||
"kotlin.LongArray.<init>",
|
||||
"kotlin.CharArray.<init>",
|
||||
"kotlin.BooleanArray.<init>"
|
||||
)
|
||||
// Enforce inlining of some constructors.
|
||||
|
||||
internal val FunctionDescriptor.needsInlining: Boolean
|
||||
get() {
|
||||
val needs = this.isInline && !this.isExternal
|
||||
if (valueParameters.size != 2) return needs // Constructor must have two parameters.
|
||||
if (mustInlineFunctions.contains(fqNameSafe.toString())) return true
|
||||
return needs
|
||||
val inlineConstructor = annotations.hasAnnotation(FqName("konan.internal.InlineConstructor"))
|
||||
if (inlineConstructor) return true
|
||||
return (this.isInline && !this.isExternal)
|
||||
}
|
||||
|
||||
internal val FunctionDescriptor.needsSerializedIr: Boolean
|
||||
|
||||
+12
-7
@@ -40,11 +40,14 @@ import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.hasDefaultValue
|
||||
import org.jetbrains.kotlin.types.TypeProjectionImpl
|
||||
import org.jetbrains.kotlin.types.TypeSubstitutor
|
||||
|
||||
private val inlineConstructor = FqName("konan.internal.InlineConstructor")
|
||||
|
||||
//-----------------------------------------------------------------------------//
|
||||
|
||||
internal class FunctionInlining(val context: Context): IrElementTransformerVoidWithContext() {
|
||||
@@ -99,12 +102,14 @@ private class Inliner(val currentScope: ScopeWithIr, val context: Context) {
|
||||
|
||||
val copyIrElement = DeepCopyIrTreeWithDescriptors(currentScope.scope.scopeOwner, context) // Create DeepCopy for current scope.
|
||||
val substituteMap = mutableMapOf<ValueDescriptor, IrExpression>()
|
||||
var isInlineConstructor = false
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
fun inline(irCall : IrCall, // Call to be substituted.
|
||||
functionDeclaration: IrFunction): IrReturnableBlockImpl { // Function to substitute.
|
||||
|
||||
isInlineConstructor = irCall.descriptor.annotations.hasAnnotation(inlineConstructor)
|
||||
val inlineFunctionBody = inlineFunction(irCall, functionDeclaration)
|
||||
val descriptorSubstitutor = copyIrElement.descriptorSubstitutorForExternalScope
|
||||
currentScope.irElement.transformChildrenVoid(descriptorSubstitutor) // Transform calls to object that might be returned from inline function call.
|
||||
@@ -365,15 +370,15 @@ private class Inliner(val currentScope: ScopeWithIr, val context: Context) {
|
||||
|
||||
fun generateIrCall(expression: IrDelegatingConstructorCallImpl): IrStatement {
|
||||
|
||||
if (!expression.descriptor.fqNameSafe.toString().contains("kotlin.IntArray.<init>")) return expression
|
||||
if (!isInlineConstructor) return expression
|
||||
|
||||
val newExpression = IrCallImpl(
|
||||
startOffset = expression.startOffset,
|
||||
endOffset = expression.endOffset,
|
||||
type = expression.descriptor.returnType,
|
||||
descriptor = expression.descriptor,
|
||||
typeArguments = expression.typeArguments,
|
||||
origin = expression.origin
|
||||
expression.startOffset,
|
||||
expression.endOffset,
|
||||
expression.descriptor.returnType,
|
||||
expression.descriptor,
|
||||
expression.typeArguments,
|
||||
expression.origin
|
||||
).apply {
|
||||
expression.descriptor.valueParameters.forEach {
|
||||
val valueArgument = expression.getValueArgument(it)
|
||||
|
||||
@@ -41,3 +41,11 @@ annotation class Intrinsic
|
||||
@Target(AnnotationTarget.FUNCTION, AnnotationTarget.CONSTRUCTOR, AnnotationTarget.CLASS)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class ExportForCompiler
|
||||
|
||||
/**
|
||||
* Annotated constructor will be inlined.
|
||||
*/
|
||||
@Target(AnnotationTarget.CONSTRUCTOR)
|
||||
@Retention(AnnotationRetention.BINARY)
|
||||
annotation class InlineConstructor
|
||||
|
||||
|
||||
@@ -16,12 +16,14 @@
|
||||
|
||||
package kotlin
|
||||
import konan.internal.ExportForCompiler
|
||||
import konan.internal.InlineConstructor
|
||||
|
||||
// TODO: remove that, as RTTI shall be per instantiation.
|
||||
@ExportTypeInfo("theArrayTypeInfo")
|
||||
public final class Array<T> {
|
||||
// Constructors are handled with compiler magic.
|
||||
public constructor(size: Int, init: (Int) -> T) {
|
||||
@InlineConstructor
|
||||
public constructor(size: Int, init: (Int) -> T): this(size) {
|
||||
var index = 0
|
||||
while (index < size) {
|
||||
this[index] = init(index)
|
||||
|
||||
@@ -25,6 +25,7 @@ import kotlin.internal.PureReifiable
|
||||
import kotlin.util.sortArrayComparable
|
||||
import kotlin.util.sortArrayWith
|
||||
import kotlin.util.sortArray
|
||||
import konan.internal.InlineConstructor
|
||||
// TODO: make all iterator() methods inline.
|
||||
|
||||
/**
|
||||
@@ -41,6 +42,7 @@ public final class ByteArray {
|
||||
* [init] function. The [init] function returns an array element given its index.
|
||||
*/
|
||||
// TODO: What about inline constructors?
|
||||
@InlineConstructor
|
||||
public constructor(size: Int, init: (Int) -> Byte): this(size) {
|
||||
for (i in 0..size - 1) {
|
||||
this[i] = init(i)
|
||||
@@ -92,6 +94,7 @@ public final class CharArray {
|
||||
* Creates a new array of the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function. The [init] function returns an array element given its index.
|
||||
*/
|
||||
@InlineConstructor
|
||||
public constructor(size: Int, init: (Int) -> Char): this(size) {
|
||||
for (i in 0..size - 1) {
|
||||
this[i] = init(i)
|
||||
@@ -142,6 +145,7 @@ public final class ShortArray {
|
||||
* Creates a new array of the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function. The [init] function returns an array element given its index.
|
||||
*/
|
||||
@InlineConstructor
|
||||
public constructor(size: Int, init: (Int) -> Short): this(size) {
|
||||
for (i in 0..size - 1) {
|
||||
this[i] = init(i)
|
||||
@@ -192,6 +196,7 @@ public final class IntArray {
|
||||
* Creates a new array of the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function. The [init] function returns an array element given its index.
|
||||
*/
|
||||
@InlineConstructor
|
||||
public constructor(size: Int, init: (Int) -> Int): this(size) {
|
||||
for (i in 0..size - 1) {
|
||||
this[i] = init(i)
|
||||
@@ -242,6 +247,7 @@ public final class LongArray {
|
||||
* Creates a new array of the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function. The [init] function returns an array element given its index.
|
||||
*/
|
||||
@InlineConstructor
|
||||
public constructor(size: Int, init: (Int) -> Long): this(size) {
|
||||
for (i in 0..size - 1) {
|
||||
this[i] = init(i)
|
||||
@@ -292,6 +298,7 @@ public final class FloatArray {
|
||||
* Creates a new array of the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function. The [init] function returns an array element given its index.
|
||||
*/
|
||||
@InlineConstructor
|
||||
public constructor(size: Int, init: (Int) -> Float): this(size) {
|
||||
for (i in 0..size - 1) {
|
||||
this[i] = init(i)
|
||||
@@ -338,6 +345,7 @@ public final class DoubleArray {
|
||||
* Creates a new array of the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function. The [init] function returns an array element given its index.
|
||||
*/
|
||||
@InlineConstructor
|
||||
public constructor(size: Int, init: (Int) -> Double): this(size) {
|
||||
for (i in 0..size - 1) {
|
||||
this[i] = init(i)
|
||||
@@ -384,6 +392,7 @@ public final class BooleanArray {
|
||||
* Creates a new array of the specified [size], where each element is calculated by calling the specified
|
||||
* [init] function. The [init] function returns an array element given its index.
|
||||
*/
|
||||
@InlineConstructor
|
||||
public constructor(size: Int, init: (Int) -> Boolean): this(size) {
|
||||
for (i in 0..size - 1) {
|
||||
this[i] = init(i)
|
||||
|
||||
Reference in New Issue
Block a user