[K/N] Initialize fields with ConstantValue initializers statically

This commit is contained in:
Pavel Kunyavskiy
2021-07-19 11:21:01 +03:00
committed by Space
parent 7a0f72105f
commit 0d11a61fb2
4 changed files with 13 additions and 19 deletions
@@ -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<IrE
private fun FunctionGenerationContext.initGlobalField(irField: IrField) {
val address = context.llvmDeclarations.forStaticField(irField).storageAddressAccess.getAddress(this)
val initialValue = if (irField.initializer?.expression !is IrConst<*>?) {
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<IrE
if (context.needGlobalInit(declaration)) {
val type = codegen.getLLVMType(declaration.type)
val globalPropertyAccess = context.llvmDeclarations.forStaticField(declaration).storageAddressAccess
val initializer = declaration.initializer?.expression as? IrConst<*>
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)
}
@@ -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
}
}
@@ -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
@@ -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 }