From 9a3bcd4c19c2cddf960f9b2da41855d2180ced7c Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Mon, 26 Dec 2016 17:13:13 +0700 Subject: [PATCH] backend: statically instantiate kotlin.Unit and optimize IrGetObjectValue(Unit) --- .../backend/konan/descriptors/DescriptorUtils.kt | 3 +++ .../kotlin/backend/konan/llvm/IrToBitcode.kt | 15 ++++++++++++--- .../kotlin/backend/konan/llvm/StaticObjects.kt | 15 +++++++++++++++ 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt index 0141c520cb9..a905d726440 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/descriptors/DescriptorUtils.kt @@ -11,6 +11,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.* import org.jetbrains.kotlin.resolve.scopes.MemberScope import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.TypeUtils +import org.jetbrains.kotlin.types.typeUtil.isUnit import org.jetbrains.kotlin.util.OperatorNameConventions /** @@ -147,3 +148,5 @@ internal val FunctionDescriptor.isFunctionInvoke: Boolean return dispatchReceiver.type.isFunctionType && this.isOperator && this.name == OperatorNameConventions.INVOKE } + +internal fun ClassDescriptor.isUnit() = this.defaultType.isUnit() diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index e04c9db17c6..0b2858e87bd 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -395,9 +395,13 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid if (constructorDescriptor.isPrimary) { if (DescriptorUtils.isObject(classDescriptor)) { - val objectPtr = objectPtrByName(classDescriptor) + if (classDescriptor.isUnit()) { + context.llvm.staticData.createUnitInstance(classDescriptor) + } else { + val objectPtr = objectPtrByName(classDescriptor) - LLVMSetInitializer(objectPtr, codegen.kNullObjHeaderPtr) + LLVMSetInitializer(objectPtr, codegen.kNullObjHeaderPtr) + } } val irOfCurrentClass = context.ir.moduleIndex.classes[classDescriptor.classId] irOfCurrentClass!!.acceptChildrenVoid(object : IrElementVisitorVoid { @@ -732,7 +736,11 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid //-------------------------------------------------------------------------// - private fun evaluateGetObjectValue(value: IrGetObjectValue): LLVMValueRef? { + private fun evaluateGetObjectValue(value: IrGetObjectValue): LLVMValueRef { + if (value.descriptor.isUnit()) { + return codegen.theUnitInstanceRef.llvm + } + var objectPtr = objectPtrByName(value.descriptor) val bbCurrent = codegen.currentBlock val bbInit = codegen.basicBlock("label_init") @@ -1421,6 +1429,7 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid //-------------------------------------------------------------------------// private fun objectPtrByName(descriptor: ClassDescriptor): LLVMValueRef? { + assert (!descriptor.isUnit()) val objName = descriptor.fqNameSafe.asString() var objectPtr = LLVMGetNamedGlobal(context.llvmModule, objName) if (objectPtr == null) { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticObjects.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticObjects.kt index 7d319411f58..97d9cd547ab 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticObjects.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/StaticObjects.kt @@ -2,6 +2,7 @@ package org.jetbrains.kotlin.backend.konan.llvm import llvm.* import org.jetbrains.kotlin.backend.konan.KonanPlatform +import org.jetbrains.kotlin.backend.konan.descriptors.isUnit import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.ir.expressions.IrConst @@ -115,3 +116,17 @@ internal fun StaticData.createArrayList(elementType: TypeProjection, array: Cons return createKotlinObject(type, body) } + +private val theUnitInstanceName = "kobj:kotlin.Unit" + +internal fun StaticData.createUnitInstance(descriptor: ClassDescriptor): ConstPointer { + assert (descriptor.isUnit()) + assert (descriptor.fields.isEmpty()) + val typeInfo = descriptor.defaultType.typeInfoPtr!! + val objHeader = objHeader(typeInfo) + val global = this.placeGlobal(theUnitInstanceName, objHeader) + return global.pointer +} + +internal val ContextUtils.theUnitInstanceRef: ConstPointer + get() = constPointer(externalGlobal(theUnitInstanceName, context.llvm.runtime.objHeaderType)) \ No newline at end of file