From 5212fd81896be65a4cf7917aba785ffd28b70137 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Tue, 24 Apr 2018 15:53:09 +0300 Subject: [PATCH] DFG: Added function attributes to FunctionSymbol --- .../konan/optimizations/DFGSerializer.kt | 16 +++---- .../backend/konan/optimizations/DataFlowIR.kt | 48 +++++++++++++------ 2 files changed, 42 insertions(+), 22 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGSerializer.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGSerializer.kt index dba6c969339..c26f91b5d18 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGSerializer.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGSerializer.kt @@ -309,14 +309,14 @@ internal object DFGSerializer { } } - class FunctionSymbolBase(val parameterTypes: IntArray, val returnType: Int, val isGlobalInitializer: Boolean) { + class FunctionSymbolBase(val parameterTypes: IntArray, val returnType: Int, val attributes: Int) { - constructor(data: ArraySlice) : this(data.readIntArray(), data.readInt(), data.readBoolean()) + constructor(data: ArraySlice) : this(data.readIntArray(), data.readInt(), data.readInt()) fun write(result: ArraySlice) { result.writeIntArray(parameterTypes) result.writeInt(returnType) - result.writeBoolean(isGlobalInitializer) + result.writeInt(attributes) } } @@ -807,7 +807,7 @@ internal object DFGSerializer { FunctionSymbolBase( symbol.parameterTypes.map { typeMap[it]!! }.toIntArray(), typeMap[symbol.returnType]!!, - symbol.isGlobalInitializer + symbol.attributes ) val symbol = it.key @@ -971,21 +971,21 @@ internal object DFGSerializer { } val functionSymbols = symbolTable.functionSymbols.map { - val isGlobalInitializer = it.base.isGlobalInitializer + val attributes = it.base.attributes val external = it.external val public = it.public val private = it.private when { external != null -> DataFlowIR.FunctionSymbol.External(external.hash, - isGlobalInitializer, external.escapes, external.pointsTo, external.name) + attributes, external.escapes, external.pointsTo, external.name) public != null -> { val symbolTableIndex = public.index if (symbolTableIndex >= 0) ++module.numberOfFunctions DataFlowIR.FunctionSymbol.Public(public.hash, - module, symbolTableIndex, isGlobalInitializer, null, public.name).also { + module, symbolTableIndex, attributes, null, public.name).also { publicFunctionsMap.put(it.hash, it) } } @@ -995,7 +995,7 @@ internal object DFGSerializer { if (symbolTableIndex >= 0) ++module.numberOfFunctions DataFlowIR.FunctionSymbol.Private(privateFunIndex++, - module, symbolTableIndex, isGlobalInitializer, null, private.name) + module, symbolTableIndex, attributes, null, private.name) } }.apply { parameterTypes = it.base.parameterTypes.map { types[it] }.toTypedArray() diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt index fff7f5c3669..ff5bd10d4c0 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt @@ -43,6 +43,8 @@ import org.jetbrains.kotlin.resolve.constants.ConstantValue import org.jetbrains.kotlin.resolve.constants.IntValue import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.typeUtil.immediateSupertypes +import org.jetbrains.kotlin.types.typeUtil.isNothing +import org.jetbrains.kotlin.types.typeUtil.isUnit internal object DataFlowIR { @@ -122,13 +124,23 @@ internal object DataFlowIR { var numberOfClasses = 0 } - abstract class FunctionSymbol(val isGlobalInitializer: Boolean, val name: String?) { + object FunctionAttributes { + val IS_GLOBAL_INITIALIZER = 1 + val RETURNS_UNIT = 2 + val RETURNS_NOTHING = 4 + } + + abstract class FunctionSymbol(val attributes: Int, val name: String?) { lateinit var parameterTypes: Array lateinit var returnType: Type - class External(val hash: Long, isGlobalInitializer: Boolean, + val isGlobalInitializer = attributes.and(FunctionAttributes.IS_GLOBAL_INITIALIZER) != 0 + val returnsUnit = attributes.and(FunctionAttributes.RETURNS_UNIT) != 0 + val returnsNothing = attributes.and(FunctionAttributes.RETURNS_NOTHING) != 0 + + class External(val hash: Long, attributes: Int, val escapes: Int?, val pointsTo: IntArray?, name: String? = null) - : FunctionSymbol(isGlobalInitializer, name) { + : FunctionSymbol(attributes, name) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -147,14 +159,14 @@ internal object DataFlowIR { } abstract class Declared(val module: Module, val symbolTableIndex: Int, - isGlobalInitializer: Boolean, var bridgeTarget: FunctionSymbol?, name: String?) - : FunctionSymbol(isGlobalInitializer, name) { + attributes: Int, var bridgeTarget: FunctionSymbol?, name: String?) + : FunctionSymbol(attributes, name) { } class Public(val hash: Long, module: Module, symbolTableIndex: Int, - isGlobalInitializer: Boolean, bridgeTarget: FunctionSymbol?, name: String? = null) - : Declared(module, symbolTableIndex, isGlobalInitializer, bridgeTarget, name) { + attributes: Int, bridgeTarget: FunctionSymbol?, name: String? = null) + : Declared(module, symbolTableIndex, attributes, bridgeTarget, name) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -173,8 +185,8 @@ internal object DataFlowIR { } class Private(val index: Int, module: Module, symbolTableIndex: Int, - isGlobalInitializer: Boolean, bridgeTarget: FunctionSymbol?, name: String? = null) - : Declared(module, symbolTableIndex, isGlobalInitializer, bridgeTarget, name) { + attributes: Int, bridgeTarget: FunctionSymbol?, name: String? = null) + : Declared(module, symbolTableIndex, attributes, bridgeTarget, name) { override fun equals(other: Any?): Boolean { if (this === other) return true @@ -538,6 +550,13 @@ internal object DataFlowIR { functionMap[it]?.let { return it } val name = if (it.isExported()) it.symbolName else it.internalName + val returnsUnit = it is ConstructorDescriptor || (!it.isSuspend && it.returnType.isUnit()) + val returnsNothing = !it.isSuspend && it.returnType.isNothing() + var attributes = 0 + if (returnsUnit) + attributes = attributes or FunctionAttributes.RETURNS_UNIT + if (returnsNothing) + attributes = attributes or FunctionAttributes.RETURNS_NOTHING val symbol = when { it.module != irModule.descriptor || it.isExternal || (it.origin == IrDeclarationOrigin.IR_BUILTINS_STUB) -> { val escapesAnnotation = it.descriptor.annotations.findAnnotation(FQ_NAME_ESCAPES) @@ -546,7 +565,7 @@ internal object DataFlowIR { val escapesBitMask = (escapesAnnotation?.allValueArguments?.get(escapesWhoDescriptor.name) as? ConstantValue)?.value @Suppress("UNCHECKED_CAST") val pointsToBitMask = (pointsToAnnotation?.allValueArguments?.get(pointsToOnWhomDescriptor.name) as? ConstantValue>)?.value - FunctionSymbol.External(name.localHash.value, false, escapesBitMask, + FunctionSymbol.External(name.localHash.value, attributes, escapesBitMask, pointsToBitMask?.let { it.map { it.value }.toIntArray() }, takeName { name }) } @@ -560,12 +579,12 @@ internal object DataFlowIR { val bridgeTargetSymbol = if (isSpecialBridge || bridgeTarget == null) null else mapFunction(bridgeTarget) val placeToFunctionsTable = !isAbstract && it !is ConstructorDescriptor && classDescriptor != null && classDescriptor.kind != ClassKind.ANNOTATION_CLASS - && (it.isOverridableOrOverrides || bridgeTarget != null || !classDescriptor.isFinal()) + && (it.isOverridableOrOverrides || bridgeTarget != null || descriptor.name.asString().contains("