backend: Support IrTypeOperator.IMPLICIT_INTEGER_COERCION
Add kotlin-compiler: 1.1-20170303.084850-431. Support IMPLICIT_INTEGER_COERCION in codegen. Remove workaround for KT-16486.
This commit is contained in:
+27
-7
@@ -2,10 +2,7 @@ package org.jetbrains.kotlin.backend.konan.llvm
|
|||||||
|
|
||||||
import kotlinx.cinterop.*
|
import kotlinx.cinterop.*
|
||||||
import llvm.*
|
import llvm.*
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.*
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
|
|
||||||
import org.jetbrains.kotlin.backend.konan.KonanPhase
|
|
||||||
import org.jetbrains.kotlin.backend.konan.PhaseManager
|
|
||||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||||
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
|
||||||
@@ -27,9 +24,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
|
|||||||
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameUnsafe
|
||||||
import org.jetbrains.kotlin.types.KotlinType
|
import org.jetbrains.kotlin.types.KotlinType
|
||||||
import org.jetbrains.kotlin.types.TypeUtils
|
import org.jetbrains.kotlin.types.TypeUtils
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isNothing
|
import org.jetbrains.kotlin.types.typeUtil.*
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isTypeParameter
|
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isUnit
|
|
||||||
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
import org.jetbrains.kotlin.utils.addToStdlib.singletonList
|
||||||
|
|
||||||
|
|
||||||
@@ -1130,6 +1125,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
private fun evaluateTypeOperator(value: IrTypeOperatorCall): LLVMValueRef {
|
private fun evaluateTypeOperator(value: IrTypeOperatorCall): LLVMValueRef {
|
||||||
when (value.operator) {
|
when (value.operator) {
|
||||||
IrTypeOperator.CAST -> return evaluateCast(value)
|
IrTypeOperator.CAST -> return evaluateCast(value)
|
||||||
|
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> return evaluateIntegerCoercion(value)
|
||||||
IrTypeOperator.IMPLICIT_CAST -> return evaluateExpression(value.argument)
|
IrTypeOperator.IMPLICIT_CAST -> return evaluateExpression(value.argument)
|
||||||
IrTypeOperator.IMPLICIT_NOTNULL -> TODO("${ir2string(value)}")
|
IrTypeOperator.IMPLICIT_NOTNULL -> TODO("${ir2string(value)}")
|
||||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> {
|
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> {
|
||||||
@@ -1140,7 +1136,31 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
IrTypeOperator.INSTANCEOF -> return evaluateInstanceOf(value)
|
IrTypeOperator.INSTANCEOF -> return evaluateInstanceOf(value)
|
||||||
IrTypeOperator.NOT_INSTANCEOF -> return evaluateNotInstanceOf(value)
|
IrTypeOperator.NOT_INSTANCEOF -> return evaluateNotInstanceOf(value)
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
|
private fun KotlinType.isPrimitiveInteger(): Boolean {
|
||||||
|
return isPrimitiveNumberType() &&
|
||||||
|
!KotlinBuiltIns.isFloat(this) &&
|
||||||
|
!KotlinBuiltIns.isDouble(this) &&
|
||||||
|
!KotlinBuiltIns.isChar(this)
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun evaluateIntegerCoercion(value: IrTypeOperatorCall): LLVMValueRef {
|
||||||
|
context.log("evaluateIntegerCoercion : ${ir2string(value)}")
|
||||||
|
val type = value.typeOperand
|
||||||
|
assert(type.isPrimitiveInteger())
|
||||||
|
val result = evaluateExpression(value.argument)
|
||||||
|
val llvmSrcType = codegen.getLLVMType(value.argument.type)
|
||||||
|
val llvmDstType = codegen.getLLVMType(type)
|
||||||
|
val srcWidth = LLVMGetIntTypeWidth(llvmSrcType)
|
||||||
|
val dstWidth = LLVMGetIntTypeWidth(llvmDstType)
|
||||||
|
return when {
|
||||||
|
srcWidth == dstWidth -> result
|
||||||
|
srcWidth > dstWidth -> LLVMBuildTrunc(codegen.builder, result, llvmDstType, "")!!
|
||||||
|
else /* srcWidth < dstWidth */ -> LLVMBuildSExt(codegen.builder, result, llvmDstType, "")!!
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|||||||
+4
-2
@@ -51,7 +51,8 @@ private class AutoboxingTransformer(val context: Context) : AbstractValueUsageTr
|
|||||||
}
|
}
|
||||||
|
|
||||||
override fun IrExpression.useInTypeOperator(operator: IrTypeOperator, typeOperand: KotlinType): IrExpression {
|
override fun IrExpression.useInTypeOperator(operator: IrTypeOperator, typeOperand: KotlinType): IrExpression {
|
||||||
return if (operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT) {
|
return if (operator == IrTypeOperator.IMPLICIT_COERCION_TO_UNIT ||
|
||||||
|
operator == IrTypeOperator.IMPLICIT_INTEGER_COERCION) {
|
||||||
this
|
this
|
||||||
} else {
|
} else {
|
||||||
// Codegen expects the argument of type-checking operator to be an object reference:
|
// Codegen expects the argument of type-checking operator to be an object reference:
|
||||||
@@ -68,7 +69,8 @@ private class AutoboxingTransformer(val context: Context) : AbstractValueUsageTr
|
|||||||
val newTypeOperand = getRuntimeReferenceType(expression.typeOperand)
|
val newTypeOperand = getRuntimeReferenceType(expression.typeOperand)
|
||||||
|
|
||||||
return when (expression.operator) {
|
return when (expression.operator) {
|
||||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> expression
|
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT,
|
||||||
|
IrTypeOperator.IMPLICIT_INTEGER_COERCION -> expression
|
||||||
|
|
||||||
IrTypeOperator.CAST, IrTypeOperator.IMPLICIT_CAST,
|
IrTypeOperator.CAST, IrTypeOperator.IMPLICIT_CAST,
|
||||||
IrTypeOperator.IMPLICIT_NOTNULL, IrTypeOperator.SAFE_CAST -> {
|
IrTypeOperator.IMPLICIT_NOTNULL, IrTypeOperator.SAFE_CAST -> {
|
||||||
|
|||||||
+1
-7
@@ -60,10 +60,6 @@ internal class ClassDelegationLowering(val context: Context) : DeclarationContai
|
|||||||
val statement = body.statements.single()
|
val statement = body.statements.single()
|
||||||
val delegatedCall = ((statement as? IrReturn)?.value ?: statement) as? IrCall
|
val delegatedCall = ((statement as? IrReturn)?.value ?: statement) as? IrCall
|
||||||
?: throw AssertionError("Unexpected method body: $statement")
|
?: throw AssertionError("Unexpected method body: $statement")
|
||||||
val propertyGetter = delegatedCall.dispatchReceiver as? IrGetValue
|
|
||||||
?: throw AssertionError("Unexpected dispatch receiver: ${delegatedCall.dispatchReceiver}")
|
|
||||||
val propertyDescriptor = propertyGetter.descriptor as? PropertyDescriptor
|
|
||||||
?: throw AssertionError("Unexpected dispatch receiver descriptor: ${propertyGetter.descriptor}")
|
|
||||||
val delegated = context.specialDescriptorsFactory.getBridgeDescriptor(
|
val delegated = context.specialDescriptorsFactory.getBridgeDescriptor(
|
||||||
OverriddenFunctionDescriptor(descriptor, delegatedCall.descriptor as FunctionDescriptor))
|
OverriddenFunctionDescriptor(descriptor, delegatedCall.descriptor as FunctionDescriptor))
|
||||||
val newFunction = IrFunctionImpl(irFunction.startOffset, irFunction.endOffset, irFunction.origin, delegated)
|
val newFunction = IrFunctionImpl(irFunction.startOffset, irFunction.endOffset, irFunction.origin, delegated)
|
||||||
@@ -71,9 +67,7 @@ internal class ClassDelegationLowering(val context: Context) : DeclarationContai
|
|||||||
val irBlockBody = IrBlockBodyImpl(irFunction.startOffset, irFunction.endOffset)
|
val irBlockBody = IrBlockBodyImpl(irFunction.startOffset, irFunction.endOffset)
|
||||||
val returnType = delegatedCall.descriptor.returnType!!
|
val returnType = delegatedCall.descriptor.returnType!!
|
||||||
val irCall = IrCallImpl(irFunction.startOffset, irFunction.endOffset, returnType, delegatedCall.descriptor, null)
|
val irCall = IrCallImpl(irFunction.startOffset, irFunction.endOffset, returnType, delegatedCall.descriptor, null)
|
||||||
val receiver = IrGetValueImpl(irFunction.startOffset, irFunction.endOffset,
|
irCall.dispatchReceiver = delegatedCall.dispatchReceiver
|
||||||
(irDeclarationContainer as IrClass).descriptor.thisAsReceiverParameter)
|
|
||||||
irCall.dispatchReceiver = IrGetFieldImpl(irFunction.startOffset, irFunction.endOffset, propertyDescriptor, receiver)
|
|
||||||
irCall.extensionReceiver = delegated.extensionReceiverParameter?.let { extensionReceiver ->
|
irCall.extensionReceiver = delegated.extensionReceiverParameter?.let { extensionReceiver ->
|
||||||
IrGetValueImpl(irFunction.startOffset, irFunction.endOffset, extensionReceiver)
|
IrGetValueImpl(irFunction.startOffset, irFunction.endOffset, extensionReceiver)
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -2,4 +2,4 @@ kotlin_version=1.1-M03
|
|||||||
llvmVersion = 3.9.0
|
llvmVersion = 3.9.0
|
||||||
minMacOsVersion = 10.10
|
minMacOsVersion = 10.10
|
||||||
#kotlinCompilerModule=org.jetbrains.kotlin:kotlin-compiler:1.1-SNAPSHOT
|
#kotlinCompilerModule=org.jetbrains.kotlin:kotlin-compiler:1.1-SNAPSHOT
|
||||||
kotlinCompilerModule=org.jetbrains.kotlin:kotlin-compiler:1.1-20170224.164531-429
|
kotlinCompilerModule=org.jetbrains.kotlin:kotlin-compiler:1.1-20170303.084850-431
|
||||||
Reference in New Issue
Block a user