New tests added

This commit is contained in:
Konstantin Anisimov
2017-03-14 17:19:06 +07:00
committed by KonstantinAnisimov
parent 39f002db81
commit 22b74c0a3a
4 changed files with 72 additions and 32 deletions
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
import org.jetbrains.kotlin.ir.util.getArguments
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.types.KotlinType
//-----------------------------------------------------------------------------//
@@ -70,7 +71,7 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
val functionDescriptor = expression.descriptor as FunctionDescriptor
if (functionDescriptor.isInline) {
val inlineFunctionBody = inlineFunction(expression)
// inlineFunctionBody.accept(this, null) //
// inlineFunctionBody.transformChildrenVoid(this) // TODO
return inlineFunctionBody // Return newly created IrInlineBody instead of IrCall.
}
@@ -86,9 +87,9 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
.functions[functionDescriptor.original] // Get FunctionDeclaration by FunctionDescriptor.
if (functionDeclaration == null) return irCall // Function is declared in another module.
print(" inline file: ${currentFile!!.fileEntry.name} ") // TODO debug output
print("function: ${currentFunction!!.descriptor.name} ") // TODO debug output
println("call: ${functionDescriptor.name} ${irCall.startOffset}") // TODO debug output
// print(" inline file: ${currentFile!!.fileEntry.name} ") // TODO debug output
// print("function: ${currentFunction!!.descriptor.name} ") // TODO debug output
// println("call: ${functionDescriptor.name} ${irCall.startOffset}") // TODO debug output
val copyFuncDeclaration = functionDeclaration.accept(DeepCopyIrTree(), // Create copy of the function.
null) as IrFunction
@@ -102,17 +103,16 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
val statements = blockBody.statements
val inlineBody = IrInlineFunctionBody(startOffset, endOffset, returnType, null, statements)
val parameterToArgument: MutableList <Pair <ValueDescriptor, IrExpression>> = irCall.getArguments().toMutableList()
val typeArgsMap = (irCall as IrMemberAccessExpressionBase).typeArguments // If there are no type args - do nothing.
val lambdaInliner = LambdaInliner(parameterToArgument)
inlineBody.transformChildrenVoid(lambdaInliner)
val typeArgsMap = (irCall as IrMemberAccessExpressionBase).typeArguments
val statementsBuf = mutableListOf<IrStatement>()
val transformer = ParametersTransformer(parameterToArgument, typeArgsMap, statementsBuf)
inlineBody.accept(transformer, null) // Replace parameters with expression.
inlineBody.transformChildrenVoid(transformer) // Replace parameters with expression.
inlineBody.statements.addAll(0, statementsBuf)
val lambdaInliner = LambdaInliner(parameterToArgument)
inlineBody.accept(lambdaInliner, null)
return inlineBody
}
@@ -251,51 +251,51 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
//---------------------------------------------------------------------//
fun getLambdaFunction(lambdaArgument: IrExpression): IrFunction? {
if (lambdaArgument !is IrBlock) return null
fun getLambdaFunction(lambdaArgument: IrExpression): IrFunction? {
if (lambdaArgument !is IrBlock) return null
if (lambdaArgument.origin != IrStatementOrigin.ANONYMOUS_FUNCTION &&
lambdaArgument.origin != IrStatementOrigin.LAMBDA) {
if (lambdaArgument.origin != IrStatementOrigin.ANONYMOUS_FUNCTION &&
lambdaArgument.origin != IrStatementOrigin.LAMBDA) {
return null
}
return null
}
// TODO: the following checks must be asserts, however it is not sane until the bugs are fixed.
// TODO: the following checks must be asserts, however it is not sane until the bugs are fixed.
val statements = lambdaArgument.statements
if (statements.size != 2) return null
val statements = lambdaArgument.statements
if (statements.size != 2) return null
val irFunction = statements[0]
if (irFunction !is IrFunction) return null // TODO
val irFunction = statements[0]
if (irFunction !is IrFunction) return null // TODO
val irCallableReference = statements[1]
if (irCallableReference !is IrCallableReference ||
val irCallableReference = statements[1]
if (irCallableReference !is IrCallableReference ||
irCallableReference.descriptor.original != irFunction.descriptor ||
irCallableReference.getArguments().isNotEmpty()) {
return null
}
return null
}
return irFunction
}
return irFunction
}
//---------------------------------------------------------------------//
fun inlineLambda(irCall: IrCall): IrExpression {
val dispatchReceiver = irCall.dispatchReceiver as IrGetValue //
val substitute = substituteMap.find { // Find expression to replace this parameter.
val substitute = substituteMap.find { // Find expression to replace this parameter.
it.first == dispatchReceiver.descriptor
}
if (substitute == null) return super.visitCall(irCall) // It is not function parameter - nothing to substitute.
val lambdaArgument = substitute.second
val lambdaFunction = getLambdaFunction(lambdaArgument)
val lambdaArgument = substitute.second
val lambdaFunction = getLambdaFunction(lambdaArgument)
if (lambdaFunction == null) return super.visitCall(irCall) // TODO
if (lambdaFunction == null) return super.visitCall(irCall) // TODO
val parameters = lambdaFunction.descriptor.valueParameters // Get lambda function parameters.
val substituteMap = parameters.map { // Iterate parameters.
val substituteMap = parameters.map { // Iterate parameters.
val parameter = it as ValueDescriptor
val argument = irCall.getValueArgument(it.index) // Get corresponding argument.
parameter to argument!! // Create (parameter -> argument) pair.
+10
View File
@@ -1454,6 +1454,11 @@ task inline10(type: RunKonanTest) {
source = "codegen/inline/inline10.kt"
}
task inline13(type: RunKonanTest) {
goldValue = "true\n"
source = "codegen/inline/inline13.kt"
}
task inline14(type: RunKonanTest) {
goldValue = "9\n"
source = "codegen/inline/inline14.kt"
@@ -1498,6 +1503,11 @@ task inline21(type: RunKonanTest) {
source = "codegen/inline/inline21.kt"
}
task inline22(type: RunKonanTest) {
goldValue = "14\n"
source = "codegen/inline/inline22.kt"
}
kotlinNativeInterop {
sysstat {
pkg 'sysstat'
@@ -0,0 +1,15 @@
open class A<T1>()
class B<T2>() : A<T2>()
@Suppress("NOTHING_TO_INLINE")
inline fun <reified T: A<*>> foo(f: Any?): Boolean {
return f is T?
}
fun bar(): Boolean {
return foo<B<Int>>(B<Int>())
}
fun main(args: Array<String>) {
println(bar().toString())
}
@@ -0,0 +1,15 @@
inline fun foo2(i2: Int): Int {
return i2 + 3
}
inline fun foo1(i1: Int): Int {
return foo2(i1)
}
fun bar(): Int {
return foo1(11)
}
fun main(args: Array<String>) {
println(bar().toString())
}