backend: Remove string concatenation from codegen

This commit is contained in:
Ilya Matveev
2017-02-03 12:32:26 +03:00
committed by ilmat192
parent 51a63222b9
commit 395b49e62b
@@ -640,7 +640,6 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
is IrWhen -> return evaluateWhen (value)
is IrThrow -> return evaluateThrow (value)
is IrTry -> return evaluateTry (value)
is IrStringConcatenation -> return evaluateStringConcatenation(value)
is IrInlineFunctionBody -> return evaluateInlineFunction (value)
is IrContainerExpression -> return evaluateContainerExpression(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 {
val exception = evaluateExpression(expression.value)
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,
bbNext: LLVMBasicBlockRef?, bbExit: LLVMBasicBlockRef?) {
val branchResult = branch.result