backend: Remove string concatenation from codegen
This commit is contained in:
-64
@@ -640,7 +640,6 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
is IrWhen -> return evaluateWhen (value)
|
is IrWhen -> return evaluateWhen (value)
|
||||||
is IrThrow -> return evaluateThrow (value)
|
is IrThrow -> return evaluateThrow (value)
|
||||||
is IrTry -> return evaluateTry (value)
|
is IrTry -> return evaluateTry (value)
|
||||||
is IrStringConcatenation -> return evaluateStringConcatenation(value)
|
|
||||||
is IrInlineFunctionBody -> return evaluateInlineFunction (value)
|
is IrInlineFunctionBody -> return evaluateInlineFunction (value)
|
||||||
is IrContainerExpression -> return evaluateContainerExpression(value)
|
is IrContainerExpression -> return evaluateContainerExpression(value)
|
||||||
is IrWhileLoop -> return evaluateWhileLoop (value)
|
is IrWhileLoop -> return evaluateWhileLoop (value)
|
||||||
@@ -816,62 +815,6 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
val kNameToString = Name.identifier("toString")
|
|
||||||
val kNameStringBuilder = Name.identifier("StringBuilder")
|
|
||||||
val kNameAppend = Name.identifier("append")
|
|
||||||
val kKotlinTextFqName = FqName.fromSegments(listOf("kotlin", "text"))
|
|
||||||
val kNameLength = Name.identifier("length")
|
|
||||||
val kStringBuilder = context.irModule?.let {
|
|
||||||
it.descriptor.getPackage(kKotlinTextFqName)
|
|
||||||
.memberScope.getContributedClassifier(kNameStringBuilder, NoLookupLocation.FROM_BACKEND) as? ClassDescriptor
|
|
||||||
}
|
|
||||||
val kStringBuilderAppendStringFn = kStringBuilder.signature2Descriptor(kNameAppend, arrayOf(KonanPlatform.builtIns.stringType))
|
|
||||||
val kStringLength = KonanPlatform.builtIns.string.getter2Descriptor(kNameLength)
|
|
||||||
val kStringBuilderToString = kStringBuilder.signature2Descriptor(kNameToString)
|
|
||||||
|
|
||||||
//TODO: make it lowering pass.
|
|
||||||
private fun evaluateStringConcatenation(value: IrStringConcatenation): LLVMValueRef {
|
|
||||||
data class Element(val string: LLVMValueRef, val llvmLenght: LLVMValueRef?, val length: Int)
|
|
||||||
|
|
||||||
val stringsWithLengths = value.arguments.map {
|
|
||||||
val evaluationResult = evaluateExpression(it)
|
|
||||||
if (it is IrConst<*> && it.kind == IrConstKind.String) {
|
|
||||||
val string = it.value as String
|
|
||||||
return@map Element(codegen.staticData.kotlinStringLiteral(it as IrConst<String>).llvm, null, string.length)
|
|
||||||
} else {
|
|
||||||
val toStringDescriptor = getToString(it.type)
|
|
||||||
val string =
|
|
||||||
if (KotlinBuiltIns.isString(it.type)) evaluationResult
|
|
||||||
else evaluateSimpleFunctionCall(
|
|
||||||
toStringDescriptor, listOf(evaluationResult), Lifetime.LOCAL)
|
|
||||||
val length = call(codegen.llvmFunction(kStringLength!!), listOf(string))
|
|
||||||
return@map Element(string, length, -1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
val constLen = stringsWithLengths
|
|
||||||
.filter { it.length != -1 }
|
|
||||||
.fold(0) { sum, (_, _, length) -> sum + length }
|
|
||||||
val totalLength = stringsWithLengths
|
|
||||||
.filter { it.length == -1 }
|
|
||||||
.fold(Int32(constLen).llvm) { sum, (_, length, _) -> codegen.plus(sum, length!!) }
|
|
||||||
|
|
||||||
val constructor = kStringBuilder!!.constructors
|
|
||||||
.firstOrNull { it -> it.valueParameters.size == 1 && KotlinBuiltIns.isInt(it.valueParameters[0].type) }!!
|
|
||||||
val stringBuilderObj = codegen.allocInstance(codegen.typeInfoValue(kStringBuilder), Lifetime.LOCAL)
|
|
||||||
|
|
||||||
call(codegen.llvmFunction(constructor), listOf(stringBuilderObj, totalLength))
|
|
||||||
|
|
||||||
stringsWithLengths.fold(stringBuilderObj) { sum, (string, _, _) ->
|
|
||||||
call(codegen.llvmFunction(kStringBuilderAppendStringFn!!), listOf(sum, string))
|
|
||||||
return@fold sum
|
|
||||||
}
|
|
||||||
|
|
||||||
return evaluateSimpleFunctionCall(kStringBuilderToString!!, listOf(stringBuilderObj),
|
|
||||||
Lifetime.GLOBAL /* TODO: fix */)
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun evaluateThrow(expression: IrThrow): LLVMValueRef {
|
private fun evaluateThrow(expression: IrThrow): LLVMValueRef {
|
||||||
val exception = evaluateExpression(expression.value)
|
val exception = evaluateExpression(expression.value)
|
||||||
currentCodeContext.genThrow(exception)
|
currentCodeContext.genThrow(exception)
|
||||||
@@ -1834,13 +1777,6 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
|||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun getToString(type: KotlinType): SimpleFunctionDescriptor {
|
|
||||||
val descriptor = type.memberScope.getContributedFunctions(kNameToString, NoLookupLocation.FROM_BACKEND).first()
|
|
||||||
return descriptor
|
|
||||||
}
|
|
||||||
|
|
||||||
//-------------------------------------------------------------------------//
|
|
||||||
|
|
||||||
private fun generateWhenCase(resultPhi: LLVMValueRef?, branch: IrBranch,
|
private fun generateWhenCase(resultPhi: LLVMValueRef?, branch: IrBranch,
|
||||||
bbNext: LLVMBasicBlockRef?, bbExit: LLVMBasicBlockRef?) {
|
bbNext: LLVMBasicBlockRef?, bbExit: LLVMBasicBlockRef?) {
|
||||||
val branchResult = branch.result
|
val branchResult = branch.result
|
||||||
|
|||||||
Reference in New Issue
Block a user