+17
-8
@@ -6,7 +6,7 @@ import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody
|
|||||||
import org.jetbrains.kotlin.backend.konan.ir.getArguments
|
import org.jetbrains.kotlin.backend.konan.ir.getArguments
|
||||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
import org.jetbrains.kotlin.descriptors.ParameterDescriptor
|
||||||
import org.jetbrains.kotlin.descriptors.impl.TypeParameterDescriptorImpl
|
import org.jetbrains.kotlin.descriptors.TypeParameterDescriptor
|
||||||
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.builders.Scope
|
import org.jetbrains.kotlin.ir.builders.Scope
|
||||||
@@ -21,7 +21,6 @@ import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
|
|||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
|
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------//
|
//-----------------------------------------------------------------------------//
|
||||||
|
|
||||||
internal class FunctionInlining(val context: Context): IrElementTransformerVoid() {
|
internal class FunctionInlining(val context: Context): IrElementTransformerVoid() {
|
||||||
@@ -30,6 +29,14 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
var fqName: String? = null
|
||||||
|
override fun visitFile(declaration: IrFile): IrFile {
|
||||||
|
fqName = declaration.packageFragmentDescriptor.fqName.asString()
|
||||||
|
return super.visitFile(declaration)
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
fun isLambdaExpression(expression: IrExpression) : Boolean {
|
fun isLambdaExpression(expression: IrExpression) : Boolean {
|
||||||
if (expression !is IrContainerExpressionBase) return false
|
if (expression !is IrContainerExpressionBase) return false
|
||||||
if (expression.origin != IrStatementOrigin.LAMBDA) return false
|
if (expression.origin != IrStatementOrigin.LAMBDA) return false
|
||||||
@@ -68,7 +75,6 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
|||||||
.functions[functionDescriptor.original] // Get FunctionDeclaration by FunctionDescriptor.
|
.functions[functionDescriptor.original] // Get FunctionDeclaration by FunctionDescriptor.
|
||||||
|
|
||||||
if (functionDeclaration == null) return super.visitCall(irCall) // Function is declared in another module.
|
if (functionDeclaration == null) return super.visitCall(irCall) // Function is declared in another module.
|
||||||
|
|
||||||
val copyFuncDeclaration = functionDeclaration.accept(DeepCopyIrTree(), // Create copy of the function.
|
val copyFuncDeclaration = functionDeclaration.accept(DeepCopyIrTree(), // Create copy of the function.
|
||||||
null) as IrFunction
|
null) as IrFunction
|
||||||
|
|
||||||
@@ -84,16 +90,18 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
|||||||
inlineBody.accept(lambdaInliner, null)
|
inlineBody.accept(lambdaInliner, null)
|
||||||
val transformer = ParametersTransformer(parameters, irCall)
|
val transformer = ParametersTransformer(parameters, irCall)
|
||||||
inlineBody.accept(transformer, null) // Replace parameters with expression.
|
inlineBody.accept(transformer, null) // Replace parameters with expression.
|
||||||
return inlineBody
|
return super.visitBlock(inlineBody)
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
val functionDescriptor = expression.descriptor as FunctionDescriptor
|
|
||||||
if (!functionDescriptor.name.asString().contains("foo")) return super.visitCall(expression)
|
|
||||||
|
|
||||||
|
if(fqName!!.contains("kotlin")) return super.visitCall(expression)
|
||||||
|
|
||||||
|
val functionDescriptor = expression.descriptor as FunctionDescriptor
|
||||||
if (functionDescriptor.isInline) return inlineFunction(expression) // Return newly created IrInlineBody instead of IrCall.
|
if (functionDescriptor.isInline) return inlineFunction(expression) // Return newly created IrInlineBody instead of IrCall.
|
||||||
|
|
||||||
return super.visitCall(expression)
|
return super.visitCall(expression)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,8 +202,9 @@ internal class ParametersTransformer(val parameterToArgument: List<Pair<Paramete
|
|||||||
val expression = super.visitTypeOperator(oldExpression) as IrTypeOperatorCall
|
val expression = super.visitTypeOperator(oldExpression) as IrTypeOperatorCall
|
||||||
|
|
||||||
val typeArgsMap = (callSite as IrMemberAccessExpressionBase).typeArguments!!
|
val typeArgsMap = (callSite as IrMemberAccessExpressionBase).typeArguments!!
|
||||||
val typeConstructor = expression.typeOperand.constructor
|
val declarationDescriptor = expression.typeOperand.constructor.declarationDescriptor
|
||||||
val typeOld = typeConstructor.declarationDescriptor as TypeParameterDescriptorImpl
|
|
||||||
|
val typeOld = declarationDescriptor as TypeParameterDescriptor
|
||||||
val typeNew = typeArgsMap[typeOld]!!
|
val typeNew = typeArgsMap[typeOld]!!
|
||||||
val startOffset = expression.startOffset
|
val startOffset = expression.startOffset
|
||||||
val endOffset = expression.endOffset
|
val endOffset = expression.endOffset
|
||||||
|
|||||||
@@ -1232,6 +1232,22 @@ task inline14(type: RunKonanTest) {
|
|||||||
source = "codegen/inline/inline14.kt"
|
source = "codegen/inline/inline14.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task inline15(type: RunKonanTest) {
|
||||||
|
goldValue = "4\n"
|
||||||
|
source = "codegen/inline/inline15.kt"
|
||||||
|
}
|
||||||
|
|
||||||
|
task inline16(type: RunKonanTest) {
|
||||||
|
disabled = true
|
||||||
|
goldValue = "false\n"
|
||||||
|
source = "codegen/inline/inline16.kt"
|
||||||
|
}
|
||||||
|
|
||||||
|
task inline17(type: RunKonanTest) {
|
||||||
|
goldValue = "[1, 2]\n"
|
||||||
|
source = "codegen/inline/inline17.kt"
|
||||||
|
}
|
||||||
|
|
||||||
kotlinNativeInterop {
|
kotlinNativeInterop {
|
||||||
sysstat {
|
sysstat {
|
||||||
pkg 'sysstat'
|
pkg 'sysstat'
|
||||||
|
|||||||
@@ -0,0 +1,17 @@
|
|||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun foo2(i1: Int): Int {
|
||||||
|
return i1 + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun foo1(i1: Int, body: (Int) -> Int): Int {
|
||||||
|
return body(i1)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(i0: Int): Int {
|
||||||
|
return foo1(i0) { foo2(it) + 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(bar(2).toString())
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun <T, C : MutableCollection<in T>> foo(destination: C, predicate: (T) -> Boolean): C {
|
||||||
|
for (element in destination) {
|
||||||
|
val value = element as T
|
||||||
|
if (!predicate(value)) destination.add(value)
|
||||||
|
}
|
||||||
|
return destination
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(): Boolean {
|
||||||
|
val result = foo <Int, MutableList<Int>> (mutableListOf(1, 2, 3)) { true }
|
||||||
|
return result.isEmpty()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(bar().toString())
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun <T> foo(i1: T, i2: T): List<T> {
|
||||||
|
return listOf(i1, i2)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(): List<Int> {
|
||||||
|
return foo <Int> (1, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(bar().toString())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user