diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 886983cd0d3..2d4742308e7 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -73,7 +73,7 @@ internal val IrField.storageKind: FieldStorageKind get() { internal fun IrField.needsGCRegistration(context: Context) = context.memoryModel == MemoryModel.EXPERIMENTAL && // only for the new MM type.binaryTypeIsReference() && // only for references - (initializer?.expression !is IrConst<*>? || // which are initialized from heap object + (hasNonConstInitializer || // which are initialized from heap object !isFinal) // or are not final internal fun IrClass.storageKind(context: Context): ObjectStorageKind = when { @@ -344,7 +344,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map?) { + val initialValue = if (irField.hasNonConstInitializer) { val initialization = evaluateExpression(irField.initializer!!.expression) if (irField.shouldBeFrozen(context)) freeze(initialization, currentCodeContext.exceptionHandler) @@ -943,11 +943,13 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map + val initializer = declaration.initializer?.expression val globalProperty = (globalPropertyAccess as? GlobalAddressAccess)?.getAddress(null) if (globalProperty != null) { - LLVMSetInitializer(globalProperty, if (initializer != null) - evaluateExpression(initializer) else LLVMConstNull(type)) + LLVMSetInitializer(globalProperty, when (initializer) { + is IrConst<*>, is IrConstantValue -> evaluateExpression(initializer) + else -> LLVMConstNull(type) + }) // (Cannot do this before the global is initialized). LLVMSetLinkage(globalProperty, LLVMLinkage.LLVMInternalLinkage) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FileInitializersLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FileInitializersLowering.kt index e9ebffb5f94..dea68cdfa55 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FileInitializersLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FileInitializersLowering.kt @@ -14,20 +14,14 @@ import org.jetbrains.kotlin.backend.konan.llvm.FieldStorageKind import org.jetbrains.kotlin.backend.konan.llvm.needsGCRegistration import org.jetbrains.kotlin.backend.konan.llvm.storageKind import org.jetbrains.kotlin.descriptors.DescriptorVisibilities -import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* -import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.IrBlockBody -import org.jetbrains.kotlin.ir.expressions.IrConst -import org.jetbrains.kotlin.ir.expressions.IrConstKind import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.util.SYNTHETIC_OFFSET import org.jetbrains.kotlin.ir.util.hasAnnotation -import org.jetbrains.kotlin.ir.util.setDeclarationsParent -import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid -import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid +import org.jetbrains.kotlin.ir.util.hasNonConstInitializer import org.jetbrains.kotlin.name.Name internal object DECLARATION_ORIGIN_MODULE_GLOBAL_INITIALIZER : IrDeclarationOriginImpl("MODULE_GLOBAL_INITIALIZER") @@ -115,11 +109,4 @@ internal class FileInitializersLowering(val context: Context) : FileLoweringPass private val IrField.needsInitializationAtRuntime: Boolean get() = hasNonConstInitializer || needsGCRegistration(context) - private val IrField.hasNonConstInitializer: Boolean - get() { - val it = initializer?.expression ?: return false - if (it !is IrConst<*>) return true - if (it.kind != IrConstKind.Null && it.type != this.type) return true // Might be boxed, so codegen won't treat it as const. - return false - } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/FileInitializersOptimization.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/FileInitializersOptimization.kt index 6c1ef09678d..8729b11b328 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/FileInitializersOptimization.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/FileInitializersOptimization.kt @@ -326,6 +326,8 @@ internal object FileInitializersOptimization { override fun visitFunctionReference(expression: IrFunctionReference, data: BitSet) = data override fun visitVararg(expression: IrVararg, data: BitSet) = data + override fun visitConstantValue(expression: IrConstantValue, data: BitSet) = data + override fun visitBreak(jump: IrBreak, data: BitSet): BitSet { intersectInitializedFiles(initializedFilesAtLoopsBreaks, jump.loop, data) return data diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/ir/util/IrUtils2.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/ir/util/IrUtils2.kt index b107eabdfce..3991383fd05 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/ir/util/IrUtils2.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/ir/util/IrUtils2.kt @@ -379,3 +379,6 @@ fun IrFunction.isRestrictedSuspendFunction(): Boolean = fun IrBuilderWithScope.irByte(value: Byte) = IrConstImpl.byte(startOffset, endOffset, context.irBuiltIns.byteType, value) + +val IrField.hasNonConstInitializer: Boolean + get() = initializer?.expression.let { it != null && it !is IrConst<*> && it !is IrConstantValue }