+3
-7
@@ -17,6 +17,9 @@ internal class KonanLower(val context: Context) {
|
|||||||
fun lower(irFile: IrFile) {
|
fun lower(irFile: IrFile) {
|
||||||
val phaser = PhaseManager(context)
|
val phaser = PhaseManager(context)
|
||||||
|
|
||||||
|
phaser.phase(KonanPhase.LOWER_INLINE) {
|
||||||
|
FunctionInlining(context).inline(irFile)
|
||||||
|
}
|
||||||
phaser.phase(KonanPhase.LOWER_ENUMS) {
|
phaser.phase(KonanPhase.LOWER_ENUMS) {
|
||||||
EnumClassLowering(context).run(irFile)
|
EnumClassLowering(context).run(irFile)
|
||||||
}
|
}
|
||||||
@@ -48,12 +51,5 @@ internal class KonanLower(val context: Context) {
|
|||||||
phaser.phase(KonanPhase.AUTOBOX) {
|
phaser.phase(KonanPhase.AUTOBOX) {
|
||||||
Autoboxing(context).lower(irFile)
|
Autoboxing(context).lower(irFile)
|
||||||
}
|
}
|
||||||
phaser.phase(KonanPhase.LOWER_INLINE) {
|
|
||||||
//FunctionInlining(context).inline(irFile)
|
|
||||||
}
|
|
||||||
|
|
||||||
phaser.phase(KonanPhase.LOWER_INTEROP) {
|
|
||||||
InteropLowering(context).runOnFilePostfix(irFile)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+11
-11
@@ -25,7 +25,7 @@ internal abstract class PlatformFlags(val distribution: Distribution) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
internal open class MacOSPlatform(distribution: Distribution)
|
internal open class MacOSPlatform(distribution: Distribution)
|
||||||
: PlatformFlags(distribution) {
|
: PlatformFlags(distribution) {
|
||||||
|
|
||||||
override val llvmLtoFlags = properties.propertyList("llvmLtoFlags.osx")
|
override val llvmLtoFlags = properties.propertyList("llvmLtoFlags.osx")
|
||||||
@@ -34,7 +34,7 @@ internal open class MacOSPlatform(distribution: Distribution)
|
|||||||
override val linkerOptimizationFlags =
|
override val linkerOptimizationFlags =
|
||||||
properties.propertyList("linkerOptimizationFlags.osx")
|
properties.propertyList("linkerOptimizationFlags.osx")
|
||||||
override val linkerKonanFlags = properties.propertyList("linkerKonanFlags.osx")
|
override val linkerKonanFlags = properties.propertyList("linkerKonanFlags.osx")
|
||||||
override val linker = "${distribution.sysRoot}/usr/bin/ld"
|
override val linker = "${distribution.sysRoot}/usr/bin/ld"
|
||||||
|
|
||||||
open val arch = properties.propertyString("arch.osx")!!
|
open val arch = properties.propertyString("arch.osx")!!
|
||||||
open val osVersionMin = properties.propertyList("osVersionMin.osx")
|
open val osVersionMin = properties.propertyList("osVersionMin.osx")
|
||||||
@@ -48,8 +48,8 @@ internal open class MacOSPlatform(distribution: Distribution)
|
|||||||
return mutableListOf<String>(linker, "-demangle") +
|
return mutableListOf<String>(linker, "-demangle") +
|
||||||
if (optimize) listOf("-object_path_lto", "temporary.o", "-lto_library", distribution.libLTO) else {listOf<String>()} +
|
if (optimize) listOf("-object_path_lto", "temporary.o", "-lto_library", distribution.libLTO) else {listOf<String>()} +
|
||||||
listOf( "-dynamic", "-arch", arch) +
|
listOf( "-dynamic", "-arch", arch) +
|
||||||
osVersionMin +
|
osVersionMin +
|
||||||
listOf("-syslibroot", "$targetSysRoot",
|
listOf("-syslibroot", "$targetSysRoot",
|
||||||
"-o", executable) +
|
"-o", executable) +
|
||||||
objectFiles +
|
objectFiles +
|
||||||
if (optimize) linkerOptimizationFlags else {listOf<String>()} +
|
if (optimize) linkerOptimizationFlags else {listOf<String>()} +
|
||||||
@@ -58,7 +58,7 @@ internal open class MacOSPlatform(distribution: Distribution)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class IPhoneOSfromMacOSPlatform(distribution: Distribution)
|
internal class IPhoneOSfromMacOSPlatform(distribution: Distribution)
|
||||||
: MacOSPlatform(distribution) {
|
: MacOSPlatform(distribution) {
|
||||||
|
|
||||||
override val arch = properties.propertyString("arch.osx-ios")!!
|
override val arch = properties.propertyString("arch.osx-ios")!!
|
||||||
@@ -67,7 +67,7 @@ internal class IPhoneOSfromMacOSPlatform(distribution: Distribution)
|
|||||||
override val targetSysRoot = "${distribution.dependencies}/${properties.propertyString("targetSysRoot.osx-ios")!!}"
|
override val targetSysRoot = "${distribution.dependencies}/${properties.propertyString("targetSysRoot.osx-ios")!!}"
|
||||||
}
|
}
|
||||||
|
|
||||||
internal class IPhoneSimulatorFromMacOSPlatform(distribution: Distribution)
|
internal class IPhoneSimulatorFromMacOSPlatform(distribution: Distribution)
|
||||||
: MacOSPlatform(distribution) {
|
: MacOSPlatform(distribution) {
|
||||||
|
|
||||||
override val arch = properties.propertyString("arch.osx-ios-sim")!!
|
override val arch = properties.propertyString("arch.osx-ios-sim")!!
|
||||||
@@ -75,7 +75,7 @@ internal class IPhoneSimulatorFromMacOSPlatform(distribution: Distribution)
|
|||||||
override val llvmLlcFlags = properties.propertyList("llvmLlcFlags.osx-ios-sim")
|
override val llvmLlcFlags = properties.propertyList("llvmLlcFlags.osx-ios-sim")
|
||||||
override val targetSysRoot = "${distribution.dependencies}/${properties.propertyString("targetSysRoot.osx-ios-sim")!!}"
|
override val targetSysRoot = "${distribution.dependencies}/${properties.propertyString("targetSysRoot.osx-ios-sim")!!}"
|
||||||
}
|
}
|
||||||
internal class LinuxPlatform(distribution: Distribution)
|
internal class LinuxPlatform(distribution: Distribution)
|
||||||
: PlatformFlags(distribution) {
|
: PlatformFlags(distribution) {
|
||||||
|
|
||||||
override val llvmLtoFlags = properties.propertyList("llvmLtoFlags.linux")
|
override val llvmLtoFlags = properties.propertyList("llvmLtoFlags.linux")
|
||||||
@@ -84,7 +84,7 @@ internal class LinuxPlatform(distribution: Distribution)
|
|||||||
override val linkerOptimizationFlags =
|
override val linkerOptimizationFlags =
|
||||||
properties.propertyList("linkerOptimizationFlags.linux")
|
properties.propertyList("linkerOptimizationFlags.linux")
|
||||||
override val linkerKonanFlags = properties.propertyList("linkerKonanFlags.linux")
|
override val linkerKonanFlags = properties.propertyList("linkerKonanFlags.linux")
|
||||||
override val linker = "${distribution.sysRoot}/../bin/ld.gold"
|
override val linker = "${distribution.sysRoot}/../bin/ld.gold"
|
||||||
|
|
||||||
val pluginOptimizationFlags =
|
val pluginOptimizationFlags =
|
||||||
properties.propertyList("pluginOptimizationFlags.linux")
|
properties.propertyList("pluginOptimizationFlags.linux")
|
||||||
@@ -122,7 +122,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
val config = context.config.configuration
|
val config = context.config.configuration
|
||||||
|
|
||||||
val targetManager = TargetManager(config)
|
val targetManager = TargetManager(config)
|
||||||
private val distribution =
|
private val distribution =
|
||||||
Distribution(context.config.configuration)
|
Distribution(context.config.configuration)
|
||||||
private val properties = distribution.properties
|
private val properties = distribution.properties
|
||||||
|
|
||||||
@@ -131,7 +131,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
KonanTarget.MACBOOK -> when (targetManager.current) {
|
KonanTarget.MACBOOK -> when (targetManager.current) {
|
||||||
KonanTarget.IPHONE_SIM
|
KonanTarget.IPHONE_SIM
|
||||||
-> IPhoneSimulatorFromMacOSPlatform(distribution)
|
-> IPhoneSimulatorFromMacOSPlatform(distribution)
|
||||||
KonanTarget.IPHONE
|
KonanTarget.IPHONE
|
||||||
-> IPhoneOSfromMacOSPlatform(distribution)
|
-> IPhoneOSfromMacOSPlatform(distribution)
|
||||||
KonanTarget.MACBOOK
|
KonanTarget.MACBOOK
|
||||||
-> MacOSPlatform(distribution)
|
-> MacOSPlatform(distribution)
|
||||||
@@ -209,7 +209,7 @@ internal class LinkStage(val context: Context) {
|
|||||||
fun linkStage() {
|
fun linkStage() {
|
||||||
context.log("# Compiler root: ${distribution.konanHome}")
|
context.log("# Compiler root: ${distribution.konanHome}")
|
||||||
|
|
||||||
val bitcodeFiles = listOf<BitcodeFile>(emitted, distribution.start, distribution.runtime,
|
val bitcodeFiles = listOf<BitcodeFile>(emitted, distribution.start, distribution.runtime,
|
||||||
distribution.launcher) + libraries
|
distribution.launcher) + libraries
|
||||||
|
|
||||||
val objectFiles = if (optimize) {
|
val objectFiles = if (optimize) {
|
||||||
|
|||||||
+2
@@ -17,6 +17,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
// TODO: remove, to make CodeGenerator descriptor-agnostic.
|
// TODO: remove, to make CodeGenerator descriptor-agnostic.
|
||||||
var constructedClass: ClassDescriptor? = null
|
var constructedClass: ClassDescriptor? = null
|
||||||
val vars = VariableManager(this)
|
val vars = VariableManager(this)
|
||||||
|
var functionDescriptor: FunctionDescriptor? = null
|
||||||
private var returnSlot: LLVMValueRef? = null
|
private var returnSlot: LLVMValueRef? = null
|
||||||
private var slotsPhi: LLVMValueRef? = null
|
private var slotsPhi: LLVMValueRef? = null
|
||||||
private var slotCount = 0
|
private var slotCount = 0
|
||||||
@@ -40,6 +41,7 @@ internal class CodeGenerator(override val context: Context) : ContextUtils {
|
|||||||
if (descriptor is ConstructorDescriptor) {
|
if (descriptor is ConstructorDescriptor) {
|
||||||
constructedClass = descriptor.constructedClass
|
constructedClass = descriptor.constructedClass
|
||||||
}
|
}
|
||||||
|
functionDescriptor = descriptor
|
||||||
}
|
}
|
||||||
|
|
||||||
fun prologue(function:LLVMValueRef, returnType:LLVMTypeRef) {
|
fun prologue(function:LLVMValueRef, returnType:LLVMTypeRef) {
|
||||||
|
|||||||
+10
-5
@@ -33,9 +33,9 @@ internal fun emitLLVM(context: Context) {
|
|||||||
|
|
||||||
val irModule = context.irModule!!
|
val irModule = context.irModule!!
|
||||||
// Note that we don't set module target explicitly.
|
// Note that we don't set module target explicitly.
|
||||||
// It is determined by the target of runtime.bc
|
// It is determined by the target of runtime.bc
|
||||||
// (see Llvm class in ContextUtils)
|
// (see Llvm class in ContextUtils)
|
||||||
// Which in turn is determined by the clang flags
|
// Which in turn is determined by the clang flags
|
||||||
// used to compile runtime.bc.
|
// used to compile runtime.bc.
|
||||||
val llvmModule = LLVMModuleCreateWithName("out")!! // TODO: dispose
|
val llvmModule = LLVMModuleCreateWithName("out")!! // TODO: dispose
|
||||||
context.llvmModule = llvmModule
|
context.llvmModule = llvmModule
|
||||||
@@ -1511,10 +1511,15 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) {
|
override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) {
|
||||||
if (KotlinBuiltIns.isUnit(inlineBody.type) == false) {
|
if (target == codegen.functionDescriptor) { // It is "non local return".
|
||||||
codegen.assignPhis(getResult()!! to value!!)
|
super.genReturn(target, value) // Generate real "return".
|
||||||
|
return
|
||||||
}
|
}
|
||||||
codegen.br(getExit()!!)
|
// It is local return.
|
||||||
|
if (KotlinBuiltIns.isUnit(inlineBody.type) == false) { // If function returns more then "unit"
|
||||||
|
codegen.assignPhis(getResult()!! to value!!) // Assign return value to result PHI node.
|
||||||
|
}
|
||||||
|
codegen.br(getExit()!!) // Generate branch on exit block.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+103
-13
@@ -1,16 +1,22 @@
|
|||||||
package org.jetbrains.kotlin.backend.konan.lower
|
package org.jetbrains.kotlin.backend.konan.lower
|
||||||
|
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
|
import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke
|
||||||
import org.jetbrains.kotlin.backend.konan.ir.IrInlineFunctionBody
|
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.ir.IrElement
|
import org.jetbrains.kotlin.ir.IrElement
|
||||||
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
|
import org.jetbrains.kotlin.ir.builders.Scope
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrContainerExpressionBase
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
||||||
import org.jetbrains.kotlin.ir.util.DeepCopyIrTree
|
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
|
||||||
|
|
||||||
//-----------------------------------------------------------------------------//
|
//-----------------------------------------------------------------------------//
|
||||||
|
|
||||||
@@ -20,27 +26,96 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoid(
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
fun isLambda(value: IrExpression) : Boolean {
|
||||||
val functionDescriptor = expression.descriptor as FunctionDescriptor
|
if (value !is IrContainerExpressionBase) return false
|
||||||
if (!functionDescriptor.isInline) return super.visitCall(expression) // Function is not to be inlined - do nothing.
|
if (value.origin != IrStatementOrigin.LAMBDA) return false
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
fun getLambdaStatements(value: IrExpression) : MutableList<IrStatement> {
|
||||||
|
val statements = (value as IrContainerExpressionBase).statements
|
||||||
|
val lambdaFunction = statements[0] as IrFunction
|
||||||
|
val lambdaBody = lambdaFunction.body as IrBlockBody
|
||||||
|
return lambdaBody.statements
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
fun getLambdaReturnType(value: IrExpression) : KotlinType {
|
||||||
|
val statements = (value as IrContainerExpressionBase).statements
|
||||||
|
val lambdaFunction = statements[0] as IrFunction
|
||||||
|
return lambdaFunction.descriptor.returnType!!
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
fun evaluateParameters(irCall: IrCall,
|
||||||
|
statements: MutableList<IrStatement>): List<Pair<ParameterDescriptor, IrExpression>> {
|
||||||
|
|
||||||
|
val scope = Scope(irCall.descriptor as FunctionDescriptor)
|
||||||
|
val parametersOld = irCall.getArguments() // Create map inline_function_parameter -> containing_function_expression.
|
||||||
|
val parametersNew = parametersOld.map {
|
||||||
|
val parameter = it.first
|
||||||
|
val expression = it.second
|
||||||
|
if (expression is IrGetValue) return@map it // There is nothing to evaluate.
|
||||||
|
if (isLambda(expression)) { // The expression is lambda.
|
||||||
|
val inlineFunctionBody = inlineLambda(expression) // Create IrInlineFunctionBody to replace this parameter.
|
||||||
|
return@map parameter to inlineFunctionBody
|
||||||
|
}
|
||||||
|
|
||||||
|
val newVar = scope.createTemporaryVariable(expression, "inline", false) // Create new variable and init it with the expression.
|
||||||
|
statements.add(0, newVar) // Add initialization of the new variable in statement list.
|
||||||
|
|
||||||
|
val getVal = IrGetValueImpl(0, 0, newVar.descriptor) // Create new IR element representing access the new variable.
|
||||||
|
parameter to getVal // Parameter will be replaced with the new variable.
|
||||||
|
}
|
||||||
|
return parametersNew
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
fun inlineFunction(irCall: IrCall): IrBlock {
|
||||||
|
|
||||||
|
val functionDescriptor = irCall.descriptor as FunctionDescriptor
|
||||||
val functionDeclaration = context.ir.originalModuleIndex
|
val functionDeclaration = context.ir.originalModuleIndex
|
||||||
.functions[functionDescriptor] // Get FunctionDeclaration by FunctionDescriptor.
|
.functions[functionDescriptor] // Get FunctionDeclaration by FunctionDescriptor.
|
||||||
if (functionDeclaration == null) return super.visitCall(expression) // Function is declared in another module.
|
val copyFuncDeclaration = functionDeclaration!!.accept(DeepCopyIrTree(), null) as IrFunction // Create copy of the function.
|
||||||
val copyFuncDeclaration = functionDeclaration.accept(DeepCopyIrTree(), null) as IrFunction // Create copy of the function.
|
|
||||||
|
|
||||||
val body = copyFuncDeclaration.body!! as IrBlockBody
|
|
||||||
val startOffset = copyFuncDeclaration.startOffset
|
val startOffset = copyFuncDeclaration.startOffset
|
||||||
val endOffset = copyFuncDeclaration.endOffset
|
val endOffset = copyFuncDeclaration.endOffset
|
||||||
val returnType = copyFuncDeclaration.descriptor.returnType!!
|
val returnType = copyFuncDeclaration.descriptor.returnType!!
|
||||||
val statements = body.statements
|
val inlineBody = copyFuncDeclaration.body!! as IrBlockBody
|
||||||
|
val statements = inlineBody.statements
|
||||||
|
val parameters = evaluateParameters(irCall, statements) // Evaluate parameters representing expression.
|
||||||
val irBlock = IrInlineFunctionBody(startOffset, endOffset, returnType, null, statements)
|
val irBlock = IrInlineFunctionBody(startOffset, endOffset, returnType, null, statements)
|
||||||
|
|
||||||
val parameterToExpression = expression.getArguments() // Build map parameter -> expression.
|
val transformer = ParametersTransformer(parameters)
|
||||||
val parametersTransformer = ParametersTransformer(parameterToExpression)
|
irBlock.accept(transformer, null) // Replace parameters with expression.
|
||||||
irBlock.accept(parametersTransformer, null) // Replace parameters with expression.
|
return irBlock
|
||||||
|
}
|
||||||
|
|
||||||
return irBlock // Return newly created IrBlock instead of IrCall.
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
fun inlineLambda(value: IrExpression): IrBlock {
|
||||||
|
|
||||||
|
val lambdaStatements = getLambdaStatements(value)
|
||||||
|
val lambdaReturnType = getLambdaReturnType(value)
|
||||||
|
val irBlock = IrInlineFunctionBody(0, 0, lambdaReturnType, null, lambdaStatements)
|
||||||
|
|
||||||
|
return irBlock
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
val functionDescriptor = expression.descriptor as FunctionDescriptor
|
||||||
|
if (!functionDescriptor.isInline) return super.visitCall(expression) // Function is not to be inlined - do nothing.
|
||||||
|
|
||||||
|
val functionDeclaration = context.ir.originalModuleIndex.functions[functionDescriptor] // Get FunctionDeclaration by FunctionDescriptor.
|
||||||
|
if (functionDeclaration == null) return super.visitCall(expression) // Function is declared in another module.
|
||||||
|
return inlineFunction(expression) // Return newly created IrBlock instead of IrCall.
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
@@ -56,12 +131,27 @@ internal class ParametersTransformer(val parameterToExpression: List <Pair<Param
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
override fun visitCall(expression: IrCall): IrExpression {
|
||||||
|
if ((expression.descriptor as FunctionDescriptor).isFunctionInvoke) { // If it is lambda call.
|
||||||
|
if (expression.dispatchReceiver !is IrGetValue) super.visitCall(expression) // Do not process such dispatch receiver.
|
||||||
|
val getValue = expression.dispatchReceiver as IrGetValue //
|
||||||
|
val parameterExpression = parameterToExpression.find { it.first == getValue.descriptor } // Find expression to replace this parameter.
|
||||||
|
if (parameterExpression == null) super.visitCall(expression) // It is not function parameter.
|
||||||
|
return parameterExpression!!.second // Replace call site with InlineFunctionBody.
|
||||||
|
}
|
||||||
|
return super.visitCall(expression) // Function is declared in another module.
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||||
val descriptor = expression.descriptor
|
val descriptor = expression.descriptor
|
||||||
if (descriptor !is ParameterDescriptor) { // TODO do we need this check?
|
if (descriptor !is ParameterDescriptor) { // TODO do we need this check?
|
||||||
return super.visitGetValue(expression)
|
return super.visitGetValue(expression)
|
||||||
}
|
}
|
||||||
val parExp = parameterToExpression.find { it.first == descriptor } // Find expression to replace this parameter.
|
val parameterExpression = parameterToExpression.find { it.first == descriptor } // Find expression to replace this parameter.
|
||||||
return parExp?.let { parExp.second } ?: super.visitGetValue(expression) // TODO should we proceed with IR iteration here?
|
if (parameterExpression == null) return super.visitGetValue(expression)
|
||||||
|
|
||||||
|
return parameterExpression.second // TODO should we proceed with IR iteration here?
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1001,11 +1001,6 @@ task memory_throw_cleanup(type: RunKonanTest) {
|
|||||||
source = "runtime/memory/throw_cleanup.kt"
|
source = "runtime/memory/throw_cleanup.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
task memory_collect_cycles(type: RunKonanTest) {
|
|
||||||
goldValue = "42\n"
|
|
||||||
source = "runtime/memory/cycles0.kt"
|
|
||||||
}
|
|
||||||
|
|
||||||
task unit1(type: RunKonanTest) {
|
task unit1(type: RunKonanTest) {
|
||||||
goldValue = "First\nkotlin.Unit\n"
|
goldValue = "First\nkotlin.Unit\n"
|
||||||
source = "codegen/basics/unit1.kt"
|
source = "codegen/basics/unit1.kt"
|
||||||
@@ -1050,6 +1045,36 @@ task vararg0(type: RunKonanTest) {
|
|||||||
source = "lower/vararg.kt"
|
source = "lower/vararg.kt"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
task inline4(type: RunKonanTest) {
|
||||||
|
goldValue = "3\n"
|
||||||
|
source = "codegen/inline/inline4.kt"
|
||||||
|
}
|
||||||
|
|
||||||
|
task inline5(type: RunKonanTest) {
|
||||||
|
goldValue = "33\n"
|
||||||
|
source = "codegen/inline/inline5.kt"
|
||||||
|
}
|
||||||
|
|
||||||
|
task inline9(type: RunKonanTest) {
|
||||||
|
goldValue = "hello\n6\n"
|
||||||
|
source = "codegen/inline/inline9.kt"
|
||||||
|
}
|
||||||
|
|
||||||
|
task inline6(type: RunKonanTest) {
|
||||||
|
goldValue = "hello1\nhello2\nhello3\nhello4\n"
|
||||||
|
source = "codegen/inline/inline6.kt"
|
||||||
|
}
|
||||||
|
|
||||||
|
task inline7(type: RunKonanTest) {
|
||||||
|
goldValue = "1\n2\n3\n"
|
||||||
|
source = "codegen/inline/inline7.kt"
|
||||||
|
}
|
||||||
|
|
||||||
|
task inline8(type: RunKonanTest) {
|
||||||
|
goldValue = "8\n"
|
||||||
|
source = "codegen/inline/inline8.kt"
|
||||||
|
}
|
||||||
|
|
||||||
kotlinNativeInterop {
|
kotlinNativeInterop {
|
||||||
sysstat {
|
sysstat {
|
||||||
pkg 'sysstat'
|
pkg 'sysstat'
|
||||||
@@ -1062,4 +1087,4 @@ task interop0(type: RunInteropKonanTest) {
|
|||||||
goldValue = "0\n0\n"
|
goldValue = "0\n0\n"
|
||||||
source = "interop/basics/0.kt"
|
source = "interop/basics/0.kt"
|
||||||
interop = 'sysstat'
|
interop = 'sysstat'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,12 @@
|
|||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun foo(i2: Int, body: () -> Int): Int {
|
||||||
|
return i2 + body()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(i1: Int): Int {
|
||||||
|
return foo(i1) { 1 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(bar(1).toString())
|
||||||
|
}
|
||||||
@@ -9,5 +9,5 @@ fun bar(i1: Int, i2: Int): Int {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fun main(args: Array<String>) {
|
fun main(args: Array<String>) {
|
||||||
println(bar(1, 8).toString())
|
println(bar(3, 8).toString())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun foo(i2: Int, body: () -> Int): Int {
|
||||||
|
return i2 + body()
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(i1: Int): Int {
|
||||||
|
return foo(i1) { return 33 }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(bar(1).toString())
|
||||||
|
}
|
||||||
|
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun foo(body: () -> Unit) {
|
||||||
|
println("hello1")
|
||||||
|
body()
|
||||||
|
println("hello4")
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
foo {
|
||||||
|
println("hello2")
|
||||||
|
println("hello3")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
bar()
|
||||||
|
}
|
||||||
@@ -0,0 +1,14 @@
|
|||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun foo(vararg args: Int) {
|
||||||
|
for (a in args) {
|
||||||
|
println(a.toString())
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar() {
|
||||||
|
foo(1, 2, 3)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
bar()
|
||||||
|
}
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun foo(i3: Int, i4: Int) : Int {
|
||||||
|
return i3 + i3 + i4
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(i1: Int, i2: Int) : Int {
|
||||||
|
return foo(i1 + i2, 2)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(bar(1, 2).toString())
|
||||||
|
}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
@Suppress("NOTHING_TO_INLINE")
|
||||||
|
inline fun foo(i3: Int, i4: Int): Int {
|
||||||
|
return i3 + i3 + i4
|
||||||
|
}
|
||||||
|
|
||||||
|
fun quiz(i: Int) : Int {
|
||||||
|
println("hello")
|
||||||
|
return i + 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fun bar(i1: Int, i2: Int): Int {
|
||||||
|
return foo(quiz(i1), i2)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun main(args: Array<String>) {
|
||||||
|
println(bar(1, 2).toString())
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user