From 6b680339724927c5d377508a107044c054f10f8c Mon Sep 17 00:00:00 2001 From: Svyatoslav Scherbina Date: Tue, 21 Feb 2017 18:15:15 +0700 Subject: [PATCH] backend: simplify vararg handling in codegen --- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 48 +++++-------------- 1 file changed, 11 insertions(+), 37 deletions(-) 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 a09f29eea8e..e8e3bdd9bd5 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 @@ -708,47 +708,21 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid //-------------------------------------------------------------------------// private fun evaluateVararg(value: IrVararg): LLVMValueRef { - var oneSizedElementsCount = 0 - data class Element(val exp: LLVMValueRef, val size: LLVMValueRef?, val isArray: Boolean) - val elements = value.elements.map { - if (it is IrSpreadElement) { - val exp = evaluateExpression(it.expression) - val array = codegen.bitcast(codegen.kArrayHeaderPtr, exp) - val sizePtr = LLVMBuildStructGEP(codegen.builder, array, 2, "") - return@map Element(exp, codegen.load(sizePtr!!), true) - } else if (it is IrExpression) { - val exp = evaluateExpression(it) - oneSizedElementsCount++ - return@map Element(exp, null, false) - } else { - TODO(ir2string(it)) + if (it is IrExpression) { + val mapped = evaluateExpression(it) + if (codegen.isConst(mapped)) { + return@map mapped + } } + + throw IllegalStateException("IrVararg neither was lowered nor can be statically evaluated") } - if (elements.all { codegen.isConst(it.exp) && !it.isArray }) { - // Note: even if all elements are const, they aren't guaranteed to be statically initialized. - // E.g. an element may be a pointer to lazy-initialized object (aka singleton). - // However it is guaranteed that all elements are already initialized at this point. - return codegen.staticData.createKotlinArray(value.type, elements.map { it.exp }) - } - - val length = LLVMConstInt(LLVMInt32Type(), oneSizedElementsCount.toLong(), 0)!! - val finalLength = elements.filter { it.isArray }.fold(length) { sum, (_, size, _) -> - codegen.plus(sum, size!!) - } - - val array = codegen.allocArray(codegen.typeInfoValue(value.type)!!, finalLength, Lifetime.GLOBAL) - elements.fold(kImmZero) { sum, (exp, size, isArray) -> - if (!isArray) { - call(context.llvm.setArrayFunction, listOf(array, sum, exp)) - return@fold codegen.plus(sum, kImmOne) - } else { - call(context.llvm.copyImplArrayFunction, listOf(exp, kImmZero, array, sum, size!!)) - return@fold codegen.plus(sum, size) - } - } - return array + // Note: even if all elements are const, they aren't guaranteed to be statically initialized. + // E.g. an element may be a pointer to lazy-initialized object (aka singleton). + // However it is guaranteed that all elements are already initialized at this point. + return codegen.staticData.createKotlinArray(value.type, elements) } //-------------------------------------------------------------------------//