Merge pull request #4496 from JetBrains/small_backend_optimizations
Small backend optimizations
This commit is contained in:
committed by
Stanislav Erokhin
parent
2c898fe72c
commit
f8b4db21aa
@@ -390,11 +390,29 @@ private class CString(val bytes: ByteArray): CValues<ByteVar>() {
|
||||
}
|
||||
}
|
||||
|
||||
private object EmptyCString: CValues<ByteVar>() {
|
||||
override val size get() = 1
|
||||
override val align get() = 1
|
||||
|
||||
private val placement =
|
||||
interpretCPointer<ByteVar>(nativeMemUtils.alloc(1, 1).rawPtr)!!.also {
|
||||
it[0] = 0.toByte()
|
||||
}
|
||||
|
||||
override fun getPointer(scope: AutofreeScope): CPointer<ByteVar> {
|
||||
return placement
|
||||
}
|
||||
override fun place(placement: CPointer<ByteVar>): CPointer<ByteVar> {
|
||||
placement[0] = 0.toByte()
|
||||
return placement
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return the value of zero-terminated UTF-8-encoded C string constructed from given [kotlin.String].
|
||||
*/
|
||||
public val String.cstr: CValues<ByteVar>
|
||||
get() = CString(encodeToUtf8(this))
|
||||
get() = if (isEmpty()) EmptyCString else CString(encodeToUtf8(this))
|
||||
|
||||
/**
|
||||
* @return the value of zero-terminated UTF-8-encoded C string constructed from given [kotlin.String].
|
||||
|
||||
+15
-3
@@ -40,6 +40,7 @@ import org.jetbrains.kotlin.backend.common.ir.copyTo
|
||||
import org.jetbrains.kotlin.backend.common.ir.copyToWithoutSuperTypes
|
||||
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
|
||||
import org.jetbrains.kotlin.ir.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFieldSymbolImpl
|
||||
@@ -47,6 +48,7 @@ import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.konan.library.KonanLibraryLayout
|
||||
import org.jetbrains.kotlin.library.SerializedIrModule
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.isEffectivelyExternal
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.getOrPut
|
||||
|
||||
/**
|
||||
* Offset for synthetic elements created by lowerings and not attributable to other places in the source code.
|
||||
@@ -254,10 +256,20 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
KonanReflectionTypes(moduleDescriptor, KonanFqNames.internalPackageName)
|
||||
}
|
||||
|
||||
val layoutBuilders = mutableMapOf<IrClass, ClassLayoutBuilder>()
|
||||
// TODO: Remove after adding special <userData> property to IrDeclaration.
|
||||
private val layoutBuilders = mutableMapOf<IrClass, ClassLayoutBuilder>()
|
||||
|
||||
fun getLayoutBuilder(irClass: IrClass) = layoutBuilders.getOrPut(irClass) {
|
||||
ClassLayoutBuilder(irClass, this, isLowered = shouldLower(this, irClass))
|
||||
fun getLayoutBuilder(irClass: IrClass): ClassLayoutBuilder {
|
||||
if (irClass is IrLazyClass)
|
||||
return layoutBuilders.getOrPut(irClass) {
|
||||
ClassLayoutBuilder(irClass, this, isLowered = shouldLower(this, irClass))
|
||||
}
|
||||
val metadata = irClass.metadata as? CodegenClassMetadata
|
||||
?: CodegenClassMetadata(irClass).also { irClass.metadata = it }
|
||||
metadata.layoutBuilder?.let { return it }
|
||||
val layoutBuilder = ClassLayoutBuilder(irClass, this, isLowered = shouldLower(this, irClass))
|
||||
metadata.layoutBuilder = layoutBuilder
|
||||
return layoutBuilder
|
||||
}
|
||||
|
||||
lateinit var globalHierarchyAnalysisResult: GlobalHierarchyAnalysisResult
|
||||
|
||||
+2
-3
@@ -5,11 +5,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.ir.konanLibrary
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.module
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
|
||||
internal abstract class LlvmModuleSpecificationBase(protected val cachedLibraries: CachedLibraries) : LlvmModuleSpecification {
|
||||
@@ -26,7 +25,7 @@ internal abstract class LlvmModuleSpecificationBase(protected val cachedLibrarie
|
||||
module.konanLibrary.let { it == null || containsLibrary(it) }
|
||||
|
||||
override fun containsDeclaration(declaration: IrDeclaration): Boolean =
|
||||
declaration.module.konanLibrary.let { it == null || containsLibrary(it) }
|
||||
declaration.konanLibrary.let { it == null || containsLibrary(it) }
|
||||
}
|
||||
|
||||
internal class DefaultLlvmModuleSpecification(cachedLibraries: CachedLibraries)
|
||||
|
||||
+11
-7
@@ -8,12 +8,11 @@ import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker
|
||||
import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.ir.konanLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
||||
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.*
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrLinker
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerIr
|
||||
import org.jetbrains.kotlin.config.CommonConfigurationKeys
|
||||
import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
@@ -154,7 +153,7 @@ internal fun Context.psiToIr(
|
||||
}
|
||||
|
||||
expectDescriptorToSymbol = mutableMapOf()
|
||||
val module = translator.generateModuleFragment(
|
||||
val mainModule = translator.generateModuleFragment(
|
||||
generatorContext,
|
||||
environment.getSourceFiles(),
|
||||
irProviders = listOf(irDeserializer),
|
||||
@@ -164,7 +163,7 @@ internal fun Context.psiToIr(
|
||||
// how ExpectedActualResolver is implemented.
|
||||
// Need to fix ExpectActualResolver to either cache expects or somehow reduce the member scope searches.
|
||||
expectDescriptorToSymbol = if (expectActualLinker) expectDescriptorToSymbol else null
|
||||
)
|
||||
).toKonanModule()
|
||||
|
||||
irDeserializer.postProcess()
|
||||
|
||||
@@ -173,7 +172,7 @@ internal fun Context.psiToIr(
|
||||
|
||||
symbolTable.noUnboundLeft("Unbound symbols left after linker")
|
||||
|
||||
module.acceptVoid(ManglerChecker(KonanManglerIr, Ir2DescriptorManglerAdapter(KonanManglerDesc)))
|
||||
mainModule.acceptVoid(ManglerChecker(KonanManglerIr, Ir2DescriptorManglerAdapter(KonanManglerDesc)))
|
||||
|
||||
val modules = if (isProducingLibrary) emptyMap() else (irDeserializer as KonanIrLinker).modules
|
||||
|
||||
@@ -182,7 +181,7 @@ internal fun Context.psiToIr(
|
||||
modules.values.forEach { fakeOverrideChecker.check(it) }
|
||||
}
|
||||
|
||||
irModule = module
|
||||
irModule = mainModule
|
||||
|
||||
// Note: coupled with [shouldLower] below.
|
||||
irModules = modules.filterValues { llvmModuleSpecification.containsModule(it) }
|
||||
@@ -196,6 +195,11 @@ internal fun Context.psiToIr(
|
||||
functionIrClassFactory.module = (modules.values + irModule!!).single { it.descriptor.isNativeStdlib() }
|
||||
}
|
||||
|
||||
mainModule.files.forEach { it.metadata = KonanFileMetadataSource(mainModule) }
|
||||
modules.values.forEach { module ->
|
||||
module.files.forEach { it.metadata = KonanFileMetadataSource(module as KonanIrModuleFragmentImpl) }
|
||||
}
|
||||
|
||||
val originalBindingContext = bindingContext as? CleanableBindingContext
|
||||
?: error("BindingContext should be cleanable in K/N IR to avoid leaking memory: $bindingContext")
|
||||
originalBindingContext.clear()
|
||||
|
||||
+2
-2
@@ -8,7 +8,7 @@ import org.jetbrains.kotlin.backend.common.lower.at
|
||||
import org.jetbrains.kotlin.backend.common.lower.irNot
|
||||
import org.jetbrains.kotlin.backend.konan.PrimitiveBinaryType
|
||||
import org.jetbrains.kotlin.backend.konan.RuntimeNames
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.ir.konanLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.getObjCMethodInfo
|
||||
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
|
||||
import org.jetbrains.kotlin.backend.konan.ir.buildSimpleAnnotation
|
||||
@@ -303,7 +303,7 @@ internal fun KotlinStubs.generateObjCCall(
|
||||
) = builder.irBlock {
|
||||
val resolved = method.resolveFakeOverride(allowAbstract = true)?: method
|
||||
val exceptionMode = ForeignExceptionMode.byValue(
|
||||
resolved.module.konanLibrary?.manifestProperties
|
||||
resolved.konanLibrary?.manifestProperties
|
||||
?.getProperty(ForeignExceptionMode.manifestKey)
|
||||
)
|
||||
|
||||
|
||||
-4
@@ -10,8 +10,6 @@ import org.jetbrains.kotlin.backend.konan.RuntimeNames
|
||||
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.annotations.AnnotationDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
|
||||
import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.resolve.OverridingUtil
|
||||
import org.jetbrains.kotlin.resolve.checkers.ExpectedActualDeclarationChecker
|
||||
@@ -156,5 +154,3 @@ internal val DeclarationDescriptor.isExpectMember: Boolean
|
||||
|
||||
internal val DeclarationDescriptor.isSerializableExpectClass: Boolean
|
||||
get() = this is ClassDescriptor && ExpectedActualDeclarationChecker.shouldGenerateExpectClass(this)
|
||||
|
||||
val ModuleDescriptor.konanLibrary get() = (this.klibModuleOrigin as? DeserializedKlibModuleOrigin)?.library
|
||||
|
||||
+29
@@ -7,9 +7,17 @@ package org.jetbrains.kotlin.backend.konan.ir
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.atMostOne
|
||||
import org.jetbrains.kotlin.backend.konan.DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.KonanMetadata
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanFileMetadataSource
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleFragmentImpl
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
|
||||
import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyDeclarationBase
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||
@@ -23,6 +31,7 @@ import org.jetbrains.kotlin.ir.types.IdSignatureValues
|
||||
import org.jetbrains.kotlin.ir.types.classifierOrFail
|
||||
import org.jetbrains.kotlin.ir.types.isMarkedNullable
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.safeAs
|
||||
@@ -101,3 +110,23 @@ fun buildSimpleAnnotation(irBuiltIns: IrBuiltIns, startOffset: Int, endOffset: I
|
||||
|
||||
internal fun IrExpression.isBoxOrUnboxCall() =
|
||||
(this is IrCall && symbol.owner.origin == DECLARATION_ORIGIN_INLINE_CLASS_SPECIAL_FUNCTION)
|
||||
|
||||
val ModuleDescriptor.konanLibrary get() = (this.klibModuleOrigin as? DeserializedKlibModuleOrigin)?.library
|
||||
val IrModuleFragment.konanLibrary get() =
|
||||
(this as? KonanIrModuleFragmentImpl)?.konanLibrary ?: descriptor.konanLibrary
|
||||
val IrFile.konanLibrary get() =
|
||||
(metadata as? KonanFileMetadataSource)?.module?.konanLibrary ?: packageFragmentDescriptor.containingDeclaration.konanLibrary
|
||||
val IrDeclaration.konanLibrary: KotlinLibrary? get() {
|
||||
((this as? IrMetadataSourceOwner)?.metadata as? KonanMetadata)?.let { return it.konanLibrary }
|
||||
val result = when (val parent = parent) {
|
||||
is IrFile -> parent.konanLibrary
|
||||
is IrPackageFragment -> parent.packageFragmentDescriptor.containingDeclaration.konanLibrary
|
||||
is IrDeclaration -> parent.konanLibrary
|
||||
else -> TODO("Unexpected declaration parent: $parent")
|
||||
}
|
||||
if (this is IrMetadataSourceOwner && this !is IrLazyDeclarationBase)
|
||||
metadata = KonanMetadata(metadata?.name, result)
|
||||
return result
|
||||
}
|
||||
|
||||
fun IrDeclaration.isFromInteropLibrary() = konanLibrary?.isInteropLibrary() == true
|
||||
|
||||
+1
-1
@@ -636,4 +636,4 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
|
||||
val llvmVector128 = vector128Type
|
||||
}
|
||||
|
||||
class IrStaticInitializer(val module: ModuleDescriptor, val initializer: LLVMValueRef)
|
||||
class IrStaticInitializer(val konanLibrary: KotlinLibrary?, val initializer: LLVMValueRef)
|
||||
|
||||
+7
-5
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.coverage.LLVMCoverageInstrumentation
|
||||
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleFragmentImpl
|
||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||
import org.jetbrains.kotlin.descriptors.Modality
|
||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||
@@ -32,6 +33,7 @@ import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||
import org.jetbrains.kotlin.konan.ForeignExceptionMode
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.konan.target.Family
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.resolve.descriptorUtil.classId
|
||||
@@ -323,7 +325,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
context.cAdapterGenerator.generateBindings(codegen)
|
||||
}
|
||||
|
||||
private fun runAndProcessInitializers(module: ModuleDescriptor, f: () -> Unit) {
|
||||
private fun runAndProcessInitializers(konanLibrary: KotlinLibrary?, f: () -> Unit) {
|
||||
// TODO: collect those two in one place.
|
||||
context.llvm.fileInitializers.clear()
|
||||
context.llvm.fileUsesThreadLocalObjects = false
|
||||
@@ -337,7 +339,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
|
||||
// Create global initialization records.
|
||||
val initNode = createInitNode(createInitBody())
|
||||
context.llvm.irStaticInitializers.add(IrStaticInitializer(module, createInitCtor(initNode)))
|
||||
context.llvm.irStaticInitializers.add(IrStaticInitializer(konanLibrary, createInitCtor(initNode)))
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
@@ -355,7 +357,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
initializeCachedBoxes(context)
|
||||
declaration.acceptChildrenVoid(this)
|
||||
|
||||
runAndProcessInitializers(declaration.descriptor) {
|
||||
runAndProcessInitializers(null) {
|
||||
// Note: it is here because it also generates some bitcode.
|
||||
context.objCExport.generate(codegen)
|
||||
|
||||
@@ -510,7 +512,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
override fun visitFile(declaration: IrFile) {
|
||||
@Suppress("UNCHECKED_CAST")
|
||||
using(FileScope(declaration)) {
|
||||
runAndProcessInitializers(declaration.packageFragmentDescriptor.module) {
|
||||
runAndProcessInitializers(declaration.konanLibrary) {
|
||||
declaration.acceptChildrenVoid(this)
|
||||
}
|
||||
}
|
||||
@@ -2424,7 +2426,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
||||
}
|
||||
|
||||
context.llvm.irStaticInitializers.forEach {
|
||||
val library = it.module.konanLibrary
|
||||
val library = it.konanLibrary
|
||||
val initializers = libraryToInitializers[library]
|
||||
?: error("initializer for not included library ${library?.libraryFile}")
|
||||
|
||||
|
||||
+57
-28
@@ -15,17 +15,14 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
internal fun createLlvmDeclarations(context: Context): LlvmDeclarations {
|
||||
val generator = DeclarationsGeneratorVisitor(context)
|
||||
context.ir.irModule.acceptChildrenVoid(generator)
|
||||
return with(generator) {
|
||||
LlvmDeclarations(
|
||||
functions, classes, fields, staticFields, uniques
|
||||
)
|
||||
}
|
||||
return LlvmDeclarations(generator.uniques)
|
||||
}
|
||||
|
||||
// Please note, that llvmName is part of the ABI, and cannot be liberally changed.
|
||||
@@ -34,22 +31,17 @@ enum class UniqueKind(val llvmName: String) {
|
||||
EMPTY_ARRAY("theEmptyArray")
|
||||
}
|
||||
|
||||
internal class LlvmDeclarations(
|
||||
private val functions: Map<IrFunction, FunctionLlvmDeclarations>,
|
||||
private val classes: Map<IrClass, ClassLlvmDeclarations>,
|
||||
private val fields: Map<IrField, FieldLlvmDeclarations>,
|
||||
private val staticFields: Map<IrField, StaticFieldLlvmDeclarations>,
|
||||
private val unique: Map<UniqueKind, UniqueLlvmDeclarations>) {
|
||||
internal class LlvmDeclarations(private val unique: Map<UniqueKind, UniqueLlvmDeclarations>) {
|
||||
fun forFunction(function: IrFunction) = forFunctionOrNull(function) ?: with(function){error("$name in $file/${parent.fqNameForIrSerialization}")}
|
||||
fun forFunctionOrNull(function: IrFunction) = functions[function]
|
||||
fun forFunctionOrNull(function: IrFunction) = (function.metadata as? CodegenFunctionMetadata)?.llvm
|
||||
|
||||
fun forClass(irClass: IrClass) = classes[irClass] ?:
|
||||
fun forClass(irClass: IrClass) = (irClass.metadata as? CodegenClassMetadata)?.llvm ?:
|
||||
error(irClass.descriptor.toString())
|
||||
|
||||
fun forField(field: IrField) = fields[field] ?:
|
||||
fun forField(field: IrField) = (field.metadata as? CodegenInstanceFieldMetadata)?.llvm ?:
|
||||
error(field.descriptor.toString())
|
||||
|
||||
fun forStaticField(field: IrField) = staticFields[field] ?:
|
||||
fun forStaticField(field: IrField) = (field.metadata as? CodegenStaticFieldMetadata)?.llvm ?:
|
||||
error(field.descriptor.toString())
|
||||
|
||||
fun forSingleton(irClass: IrClass) = forClass(irClass).singletonDeclarations ?:
|
||||
@@ -100,10 +92,6 @@ private fun ContextUtils.createClassBodyType(name: String, fields: List<IrField>
|
||||
private class DeclarationsGeneratorVisitor(override val context: Context) :
|
||||
IrElementVisitorVoid, ContextUtils {
|
||||
|
||||
val functions = mutableMapOf<IrFunction, FunctionLlvmDeclarations>()
|
||||
val classes = mutableMapOf<IrClass, ClassLlvmDeclarations>()
|
||||
val fields = mutableMapOf<IrField, FieldLlvmDeclarations>()
|
||||
val staticFields = mutableMapOf<IrField, StaticFieldLlvmDeclarations>()
|
||||
val uniques = mutableMapOf<UniqueKind, UniqueLlvmDeclarations>()
|
||||
|
||||
private class Namer(val prefix: String) {
|
||||
@@ -157,7 +145,10 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
|
||||
|
||||
override fun visitClass(declaration: IrClass) {
|
||||
if (declaration.requiresRtti()) {
|
||||
this.classes[declaration] = createClassDeclarations(declaration)
|
||||
val classLlvmDeclarations = createClassDeclarations(declaration)
|
||||
val metadata = declaration.metadata as? CodegenClassMetadata
|
||||
?: CodegenClassMetadata(declaration).also { declaration.metadata = it }
|
||||
metadata.llvm = classLlvmDeclarations
|
||||
}
|
||||
super.visitClass(declaration)
|
||||
}
|
||||
@@ -311,12 +302,16 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
|
||||
val containingClass = declaration.parent as? IrClass
|
||||
if (containingClass != null) {
|
||||
if (!containingClass.requiresRtti()) return
|
||||
val classDeclarations = this.classes[containingClass] ?:
|
||||
error(containingClass.descriptor.toString())
|
||||
val classDeclarations = (containingClass.metadata as? CodegenClassMetadata)?.llvm
|
||||
?: error(containingClass.descriptor.toString())
|
||||
val allFields = context.getLayoutBuilder(containingClass).fields
|
||||
this.fields[declaration] = FieldLlvmDeclarations(
|
||||
allFields.indexOf(declaration) + 1, // First field is ObjHeader.
|
||||
classDeclarations.bodyType
|
||||
declaration.metadata = CodegenInstanceFieldMetadata(
|
||||
declaration.metadata?.name,
|
||||
containingClass.konanLibrary,
|
||||
FieldLlvmDeclarations(
|
||||
allFields.indexOf(declaration) + 1, // First field is ObjHeader.
|
||||
classDeclarations.bodyType
|
||||
)
|
||||
)
|
||||
} else {
|
||||
// Fields are module-private, so we use internal name:
|
||||
@@ -327,7 +322,11 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
|
||||
addKotlinGlobal(name, getLLVMType(declaration.type), isExported = false)
|
||||
}
|
||||
|
||||
this.staticFields[declaration] = StaticFieldLlvmDeclarations(storage)
|
||||
declaration.metadata = CodegenStaticFieldMetadata(
|
||||
declaration.metadata?.name,
|
||||
declaration.konanLibrary,
|
||||
StaticFieldLlvmDeclarations(storage)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -346,7 +345,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
|
||||
if (declaration.isTypedIntrinsic || declaration.isObjCBridgeBased()
|
||||
// All call-sites to external accessors to interop properties
|
||||
// are lowered by InteropLowering.
|
||||
|| (declaration.isAccessor && declaration.isFromMetadataInteropLibrary())
|
||||
|| (declaration.isAccessor && declaration.isFromInteropLibrary())
|
||||
|| declaration.annotations.hasAnnotation(RuntimeNames.cCall)) return
|
||||
|
||||
context.llvm.externalFunction(declaration.symbolName, llvmFunctionType,
|
||||
@@ -374,6 +373,36 @@ private class DeclarationsGeneratorVisitor(override val context: Context) :
|
||||
function
|
||||
}
|
||||
|
||||
this.functions[declaration] = FunctionLlvmDeclarations(llvmFunction)
|
||||
declaration.metadata = CodegenFunctionMetadata(
|
||||
declaration.metadata?.name,
|
||||
declaration.konanLibrary,
|
||||
FunctionLlvmDeclarations(llvmFunction)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
internal open class KonanMetadata(override val name: Name?, val konanLibrary: KotlinLibrary?) : MetadataSource
|
||||
|
||||
internal class CodegenClassMetadata(irClass: IrClass)
|
||||
: KonanMetadata(irClass.metadata?.name, irClass.konanLibrary), MetadataSource.Class {
|
||||
var layoutBuilder: ClassLayoutBuilder? = null
|
||||
var llvm: ClassLlvmDeclarations? = null
|
||||
}
|
||||
|
||||
private class CodegenFunctionMetadata(
|
||||
name: Name?,
|
||||
konanLibrary: KotlinLibrary?,
|
||||
val llvm: FunctionLlvmDeclarations
|
||||
) : KonanMetadata(name, konanLibrary), MetadataSource.Function
|
||||
|
||||
private class CodegenInstanceFieldMetadata(
|
||||
name: Name?,
|
||||
konanLibrary: KotlinLibrary?,
|
||||
val llvm: FieldLlvmDeclarations
|
||||
) : KonanMetadata(name, konanLibrary), MetadataSource.Property
|
||||
|
||||
private class CodegenStaticFieldMetadata(
|
||||
name: Name?,
|
||||
konanLibrary: KotlinLibrary?,
|
||||
val llvm: StaticFieldLlvmDeclarations
|
||||
) : KonanMetadata(name, konanLibrary), MetadataSource.Property
|
||||
+20
-12
@@ -53,6 +53,10 @@ internal class WorkersBridgesBuilding(val context: Context) : DeclarationContain
|
||||
private fun buildWorkerBridges(declaration: IrDeclaration): List<IrFunction> {
|
||||
val bridges = mutableListOf<IrFunction>()
|
||||
declaration.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||
override fun visitClass(declaration: IrClass): IrStatement {
|
||||
// Skip nested.
|
||||
return declaration
|
||||
}
|
||||
|
||||
override fun visitCall(expression: IrCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
@@ -133,20 +137,24 @@ internal class BridgesBuilding(val context: Context) : ClassLoweringPass {
|
||||
override fun lower(irClass: IrClass) {
|
||||
val builtBridges = mutableSetOf<IrSimpleFunction>()
|
||||
|
||||
irClass.simpleFunctions()
|
||||
.forEach { function ->
|
||||
function.allOverriddenFunctions
|
||||
.map { OverriddenFunctionInfo(function, it) }
|
||||
.filter { !it.bridgeDirections.allNotNeeded() }
|
||||
.filter { it.canBeCalledVirtually }
|
||||
.filter { !it.inheritsBridge }
|
||||
.distinctBy { it.bridgeDirections }
|
||||
.forEach {
|
||||
buildBridge(it, irClass)
|
||||
builtBridges += it.function
|
||||
}
|
||||
for (function in irClass.simpleFunctions()) {
|
||||
val set = mutableSetOf<BridgeDirections>()
|
||||
for (overriddenFunction in function.allOverriddenFunctions) {
|
||||
val overriddenFunctionInfo = OverriddenFunctionInfo(function, overriddenFunction)
|
||||
val bridgeDirections = overriddenFunctionInfo.bridgeDirections
|
||||
if (!bridgeDirections.allNotNeeded() && overriddenFunctionInfo.canBeCalledVirtually
|
||||
&& !overriddenFunctionInfo.inheritsBridge && set.add(bridgeDirections)) {
|
||||
buildBridge(overriddenFunctionInfo, irClass)
|
||||
builtBridges += function
|
||||
}
|
||||
}
|
||||
}
|
||||
irClass.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||
override fun visitClass(declaration: IrClass): IrStatement {
|
||||
// Skip nested.
|
||||
return declaration
|
||||
}
|
||||
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
declaration.transformChildrenVoid(this)
|
||||
|
||||
|
||||
+12
-5
@@ -16,6 +16,7 @@ import org.jetbrains.kotlin.backend.konan.DECLARATION_ORIGIN_ENUM
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.IntrinsicType
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.tryGetIntrinsicType
|
||||
import org.jetbrains.kotlin.descriptors.ClassKind
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrPropertyImpl
|
||||
@@ -124,19 +125,25 @@ internal class EnumUsageLowering(val context: Context)
|
||||
}
|
||||
}
|
||||
|
||||
internal class EnumClassLowering(val context: Context) : ClassLoweringPass {
|
||||
internal class EnumClassLowering(val context: Context) : FileLoweringPass {
|
||||
|
||||
fun run(irFile: IrFile) {
|
||||
// EnumWhenLowering should be performed before EnumUsageLowering because
|
||||
// the latter performs lowering of IrGetEnumValue
|
||||
EnumWhenLowering(context).lower(irFile)
|
||||
runOnFilePostfix(irFile)
|
||||
lower(irFile)
|
||||
EnumUsageLowering(context).lower(irFile)
|
||||
}
|
||||
|
||||
override fun lower(irClass: IrClass) {
|
||||
if (irClass.kind != ClassKind.ENUM_CLASS) return
|
||||
EnumClassTransformer(irClass).run()
|
||||
override fun lower(irFile: IrFile) {
|
||||
irFile.transformChildrenVoid(object : IrElementTransformerVoid() {
|
||||
override fun visitClass(declaration: IrClass): IrStatement {
|
||||
declaration.transformChildrenVoid()
|
||||
if (declaration.kind == ClassKind.ENUM_CLASS)
|
||||
EnumClassTransformer(declaration).run()
|
||||
return declaration
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
private inner class EnumClassTransformer(val irClass: IrClass) {
|
||||
|
||||
+6
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||
import org.jetbrains.kotlin.backend.common.lower.callsSuper
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrBlockBody
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
@@ -87,6 +88,11 @@ internal class InnerClassLowering(val context: Context) : ClassLoweringPass {
|
||||
|
||||
private fun lowerOuterThisReferences() {
|
||||
irClass.transformChildrenVoid(object : IrElementTransformerVoidWithContext() {
|
||||
override fun visitClassNew(declaration: IrClass): IrStatement {
|
||||
// Skip nested.
|
||||
return declaration
|
||||
}
|
||||
|
||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
|
||||
+2
-4
@@ -14,8 +14,6 @@ import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.konan.*
|
||||
import org.jetbrains.kotlin.backend.konan.cgen.*
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.allOverriddenFunctions
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
|
||||
import org.jetbrains.kotlin.backend.konan.ir.*
|
||||
import org.jetbrains.kotlin.backend.konan.ir.companionObject
|
||||
@@ -811,7 +809,7 @@ private class InteropTransformer(val context: Context, override val irFile: IrFi
|
||||
private fun tryGenerateInteropConstantRead(expression: IrCall): IrExpression? {
|
||||
val function = expression.symbol.owner
|
||||
|
||||
if (!function.descriptor.module.isFromInteropLibrary()) return null
|
||||
if (!function.isFromInteropLibrary()) return null
|
||||
if (!function.isGetter) return null
|
||||
|
||||
val constantProperty = (function as? IrSimpleFunction)
|
||||
@@ -870,7 +868,7 @@ private class InteropTransformer(val context: Context, override val irFile: IrFi
|
||||
if (function.annotations.hasAnnotation(RuntimeNames.cCall)) {
|
||||
context.llvmImports.add(function.llvmSymbolOrigin)
|
||||
val exceptionMode = ForeignExceptionMode.byValue(
|
||||
function.module.konanLibrary?.manifestProperties?.getProperty(ForeignExceptionMode.manifestKey)
|
||||
function.konanLibrary?.manifestProperties?.getProperty(ForeignExceptionMode.manifestKey)
|
||||
)
|
||||
return generateWithStubs { generateCCall(expression, builder, isInvoke = false, exceptionMode) }
|
||||
}
|
||||
|
||||
+6
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.backend.konan.KonanBackendContext
|
||||
import org.jetbrains.kotlin.builtins.PrimitiveType
|
||||
import org.jetbrains.kotlin.builtins.UnsignedType
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
@@ -61,6 +62,11 @@ internal class VarargInjectionLowering constructor(val context: KonanBackendCont
|
||||
|
||||
private fun lower(owner: IrSymbol, element: IrElement?) {
|
||||
element?.transformChildrenVoid(object: IrElementTransformerVoid() {
|
||||
override fun visitClass(declaration: IrClass): IrStatement {
|
||||
// Skip nested.
|
||||
return declaration
|
||||
}
|
||||
|
||||
val transformer = this
|
||||
|
||||
private fun replaceEmptyParameterWithEmptyArray(expression: IrFunctionAccessExpression) {
|
||||
|
||||
+45
-7
@@ -24,22 +24,24 @@ import org.jetbrains.kotlin.backend.common.serialization.encodings.BinarySymbolD
|
||||
import org.jetbrains.kotlin.backend.common.serialization.signature.IdSignatureSerializer
|
||||
import org.jetbrains.kotlin.backend.konan.CachedLibraries
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.isInteropLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
|
||||
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs
|
||||
import org.jetbrains.kotlin.backend.konan.ir.konanLibrary
|
||||
import org.jetbrains.kotlin.descriptors.*
|
||||
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
|
||||
import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib
|
||||
import org.jetbrains.kotlin.descriptors.konan.klibModuleOrigin
|
||||
import org.jetbrains.kotlin.descriptors.konan.kotlinLibrary
|
||||
import org.jetbrains.kotlin.ir.builders.TranslationPluginContext
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrAbstractFunctionFactory
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrFileSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.library.IrLibrary
|
||||
import org.jetbrains.kotlin.library.KotlinLibrary
|
||||
import org.jetbrains.kotlin.name.ClassId
|
||||
@@ -107,8 +109,13 @@ internal class KonanIrLinker(
|
||||
return KonanModuleDeserializer(moduleDescriptor, klib ?: error("Expecting kotlin library"), strategy)
|
||||
}
|
||||
|
||||
private inner class KonanModuleDeserializer(moduleDescriptor: ModuleDescriptor, klib: IrLibrary, strategy: DeserializationStrategy):
|
||||
KotlinIrLinker.BasicIrModuleDeserializer(moduleDescriptor, klib, strategy)
|
||||
private inner class KonanModuleDeserializer(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
klib: IrLibrary,
|
||||
strategy: DeserializationStrategy
|
||||
): KotlinIrLinker.BasicIrModuleDeserializer(moduleDescriptor, klib, strategy) {
|
||||
override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns, emptyList())
|
||||
}
|
||||
|
||||
private inner class KonanInteropModuleDeserializer(
|
||||
moduleDescriptor: ModuleDescriptor,
|
||||
@@ -160,7 +167,7 @@ internal class KonanIrLinker(
|
||||
return symbolOwner.symbol
|
||||
}
|
||||
|
||||
override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, builtIns)
|
||||
override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns)
|
||||
override val moduleDependencies: Collection<IrModuleDeserializer> = listOfNotNull(forwardDeclarationDeserializer)
|
||||
}
|
||||
|
||||
@@ -208,7 +215,7 @@ internal class KonanIrLinker(
|
||||
return declaredDeclaration.getOrPut(idSig) { buildForwardDeclarationStub(descriptor) }.symbol
|
||||
}
|
||||
|
||||
override val moduleFragment: IrModuleFragment = IrModuleFragmentImpl(moduleDescriptor, builtIns)
|
||||
override val moduleFragment: IrModuleFragment = KonanIrModuleFragmentImpl(moduleDescriptor, builtIns)
|
||||
override val moduleDependencies: Collection<IrModuleDeserializer> = emptyList()
|
||||
}
|
||||
|
||||
@@ -226,3 +233,34 @@ internal class KonanIrLinker(
|
||||
override val irBuiltIns: IrBuiltIns
|
||||
):TranslationPluginContext
|
||||
}
|
||||
|
||||
class KonanIrModuleFragmentImpl(
|
||||
override val descriptor: ModuleDescriptor,
|
||||
override val irBuiltins: IrBuiltIns,
|
||||
files: List<IrFile> = emptyList(),
|
||||
) : IrModuleFragment() {
|
||||
override val name: Name get() = descriptor.name // TODO
|
||||
|
||||
override val files: MutableList<IrFile> = files.toMutableList()
|
||||
|
||||
val konanLibrary = (descriptor.klibModuleOrigin as? DeserializedKlibModuleOrigin)?.library
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitModuleFragment(this, data)
|
||||
|
||||
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
|
||||
files.forEach { it.accept(visitor, data) }
|
||||
}
|
||||
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
files.forEachIndexed { i, irFile ->
|
||||
files[i] = irFile.transform(transformer, data)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun IrModuleFragment.toKonanModule() = KonanIrModuleFragmentImpl(descriptor, irBuiltins, files)
|
||||
|
||||
class KonanFileMetadataSource(val module: KonanIrModuleFragmentImpl) : MetadataSource.File {
|
||||
override val name: Name? = null
|
||||
}
|
||||
Reference in New Issue
Block a user