Fix basic blocks order for WHEN expression
Merge-request: KT-MR-6833 Merged-by: Vladimir Sukharev <Vladimir.Sukharev@jetbrains.com>
This commit is contained in:
+50
-29
@@ -1283,12 +1283,16 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
* }
|
* }
|
||||||
* we cannot determine if the result of when is assigned or not.
|
* we cannot determine if the result of when is assigned or not.
|
||||||
*/
|
*/
|
||||||
private inner class WhenEmittingContext(val expression: IrWhen) {
|
private inner class WhenEmittingContext(val expression: IrWhen, val lastBBOfWhenCases: LLVMBasicBlockRef) {
|
||||||
val needsPhi = expression.branches.last().isUnconditional() && !expression.type.isUnit()
|
val needsPhi = expression.branches.last().isUnconditional() && !expression.type.isUnit()
|
||||||
val llvmType = codegen.getLLVMType(expression.type)
|
val llvmType = codegen.getLLVMType(expression.type)
|
||||||
|
|
||||||
val bbExit = lazy { functionGenerationContext.basicBlock("when_exit", expression.endLocation) }
|
val bbExit = lazy {
|
||||||
|
// bbExit must be positioned after all blocks of WHEN construct
|
||||||
|
functionGenerationContext.appendingTo(lastBBOfWhenCases) {
|
||||||
|
functionGenerationContext.basicBlock("when_exit", expression.endLocation)
|
||||||
|
}
|
||||||
|
}
|
||||||
val resultPhi = lazy {
|
val resultPhi = lazy {
|
||||||
functionGenerationContext.appendingTo(bbExit.value) {
|
functionGenerationContext.appendingTo(bbExit.value) {
|
||||||
functionGenerationContext.phi(llvmType)
|
functionGenerationContext.phi(llvmType)
|
||||||
@@ -1296,19 +1300,35 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** For WHEN { COND1 -> CASE1, COND2 -> CASE2, ELSE -> UNCONDITIONAL }
|
||||||
|
* the following sequence of basic blocks is generated:
|
||||||
|
* -- if COND1
|
||||||
|
* -- CASE1
|
||||||
|
* -- NEXT1(if COND2)
|
||||||
|
* -- CASE2
|
||||||
|
* -- NEXT2 (UNCONDITIONAL)
|
||||||
|
* -- EXIT
|
||||||
|
*/
|
||||||
private fun evaluateWhen(expression: IrWhen, resultSlot: LLVMValueRef?): LLVMValueRef {
|
private fun evaluateWhen(expression: IrWhen, resultSlot: LLVMValueRef?): LLVMValueRef {
|
||||||
context.log{"evaluateWhen : ${ir2string(expression)}"}
|
context.log{"evaluateWhen : ${ir2string(expression)}"}
|
||||||
|
|
||||||
val whenEmittingContext = WhenEmittingContext(expression)
|
|
||||||
|
|
||||||
generateDebugTrambolineIf("when", expression)
|
generateDebugTrambolineIf("when", expression)
|
||||||
expression.branches.forEach {
|
|
||||||
val bbNext = if (it == expression.branches.last())
|
// First, generate all empty basic blocks for conditions and variants
|
||||||
null
|
val bbOfFirstConditionCheck = functionGenerationContext.currentBlock
|
||||||
else
|
val branchInfos: List<BranchCaseNextInfo> = expression.branches.map {
|
||||||
functionGenerationContext.basicBlock("when_next", it.startLocation, it.endLocation)
|
// Carefully create empty basic blocks and position them one after another
|
||||||
generateWhenCase(whenEmittingContext, it, bbNext, resultSlot)
|
val bbCase = if (it.isUnconditional()) null else
|
||||||
|
functionGenerationContext.basicBlock("when_case", it.startLocation, it.endLocation).apply { functionGenerationContext.positionAtEnd(this) }
|
||||||
|
val bbNext = if (it.isUnconditional() || it == expression.branches.last()) null else
|
||||||
|
functionGenerationContext.basicBlock("when_next", it.startLocation, it.endLocation).apply { functionGenerationContext.positionAtEnd(this) }
|
||||||
|
BranchCaseNextInfo(it, bbCase, bbNext, resultSlot)
|
||||||
}
|
}
|
||||||
|
// Now, exit basic block can be positioned after all blocks of WHEN expression
|
||||||
|
val whenEmittingContext = WhenEmittingContext(expression, lastBBOfWhenCases = functionGenerationContext.currentBlock)
|
||||||
|
functionGenerationContext.positionAtEnd(bbOfFirstConditionCheck)
|
||||||
|
|
||||||
|
branchInfos.forEach { generateWhenCase(whenEmittingContext, it) }
|
||||||
|
|
||||||
if (whenEmittingContext.bbExit.isInitialized())
|
if (whenEmittingContext.bbExit.isInitialized())
|
||||||
functionGenerationContext.positionAtEnd(whenEmittingContext.bbExit.value)
|
functionGenerationContext.positionAtEnd(whenEmittingContext.bbExit.value)
|
||||||
@@ -1330,25 +1350,26 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun generateWhenCase(whenEmittingContext: WhenEmittingContext, branch: IrBranch, bbNext: LLVMBasicBlockRef?, resultSlot: LLVMValueRef?) {
|
private data class BranchCaseNextInfo(val branch: IrBranch, val bbCase: LLVMBasicBlockRef?, val bbNext: LLVMBasicBlockRef?,
|
||||||
val brResult = if (branch.isUnconditional())
|
val resultSlot: LLVMValueRef?)
|
||||||
evaluateExpression(branch.result, resultSlot)
|
|
||||||
else {
|
|
||||||
val bbCase = functionGenerationContext.basicBlock("when_case", branch.startLocation, branch.endLocation)
|
|
||||||
val condition = evaluateExpression(branch.condition)
|
|
||||||
functionGenerationContext.condBr(condition, bbCase, bbNext ?: whenEmittingContext.bbExit.value)
|
|
||||||
functionGenerationContext.positionAtEnd(bbCase)
|
|
||||||
evaluateExpression(branch.result, resultSlot)
|
|
||||||
}
|
|
||||||
if (!functionGenerationContext.isAfterTerminator()) {
|
|
||||||
if (whenEmittingContext.needsPhi)
|
|
||||||
functionGenerationContext.assignPhis(whenEmittingContext.resultPhi.value to brResult)
|
|
||||||
functionGenerationContext.br(whenEmittingContext.bbExit.value)
|
|
||||||
}
|
|
||||||
if (bbNext != null)
|
|
||||||
functionGenerationContext.positionAtEnd(bbNext)
|
|
||||||
}
|
|
||||||
|
|
||||||
|
private fun generateWhenCase(whenEmittingContext: WhenEmittingContext, branchCaseNextInfo: BranchCaseNextInfo) {
|
||||||
|
with(branchCaseNextInfo) {
|
||||||
|
if (!branch.isUnconditional()) {
|
||||||
|
val condition = evaluateExpression(branch.condition)
|
||||||
|
functionGenerationContext.condBr(condition, bbCase, bbNext ?: whenEmittingContext.bbExit.value)
|
||||||
|
functionGenerationContext.positionAtEnd(bbCase!!)
|
||||||
|
}
|
||||||
|
val brResult = evaluateExpression(branch.result, resultSlot)
|
||||||
|
if (!functionGenerationContext.isAfterTerminator()) {
|
||||||
|
if (whenEmittingContext.needsPhi)
|
||||||
|
functionGenerationContext.assignPhis(whenEmittingContext.resultPhi.value to brResult)
|
||||||
|
functionGenerationContext.br(whenEmittingContext.bbExit.value)
|
||||||
|
}
|
||||||
|
if (bbNext != null)
|
||||||
|
functionGenerationContext.positionAtEnd(bbNext)
|
||||||
|
}
|
||||||
|
}
|
||||||
//-------------------------------------------------------------------------//
|
//-------------------------------------------------------------------------//
|
||||||
|
|
||||||
private fun evaluateWhileLoop(loop: IrWhileLoop): LLVMValueRef {
|
private fun evaluateWhileLoop(loop: IrWhileLoop): LLVMValueRef {
|
||||||
|
|||||||
@@ -6151,6 +6151,10 @@ fileCheckTest("filecheck_smoke0") {
|
|||||||
annotatedSource = project.file('filecheck/smoke0.kt')
|
annotatedSource = project.file('filecheck/smoke0.kt')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fileCheckTest("filecheck_when") {
|
||||||
|
annotatedSource = project.file('filecheck/when.kt')
|
||||||
|
}
|
||||||
|
|
||||||
if (HostManager.@Companion.hostIsMac) {
|
if (HostManager.@Companion.hostIsMac) {
|
||||||
fileCheckTest("filecheck_force_arm_instruction_set") {
|
fileCheckTest("filecheck_force_arm_instruction_set") {
|
||||||
enabled = enabled && cacheTesting == null
|
enabled = enabled && cacheTesting == null
|
||||||
|
|||||||
+16
-20
@@ -7,16 +7,14 @@ package codegen.stringConcatenationTypeNarrowing.kt53119_append_generated
|
|||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyMaybeAny
|
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyMaybeAny
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
|
||||||
|
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
|
||||||
|
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||||
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||||
|
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||||
|
|
||||||
|
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||||
|
|
||||||
// CHECK: ret %struct.ObjHeader*
|
// CHECK: ret %struct.ObjHeader*
|
||||||
@@ -26,14 +24,13 @@ fun maybeAnyMaybeAny(maybeAny1: Any?, maybeAny2: Any?): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyMaybeString
|
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyMaybeString
|
||||||
|
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||||
|
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
|
||||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
|
||||||
|
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||||
// CHECK: ret %struct.ObjHeader*
|
// CHECK: ret %struct.ObjHeader*
|
||||||
|
|
||||||
@@ -42,14 +39,13 @@ fun maybeAnyMaybeString(maybeAny1: Any?, maybeString2: String?): String {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyString
|
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyString
|
||||||
|
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||||
|
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
|
||||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
|
||||||
|
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||||
// CHECK: ret %struct.ObjHeader*
|
// CHECK: ret %struct.ObjHeader*
|
||||||
|
|
||||||
@@ -60,6 +56,8 @@ fun maybeAnyString(maybeAny1: Any?, string: String): String {
|
|||||||
data class Foo(val bar: Int)
|
data class Foo(val bar: Int)
|
||||||
|
|
||||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyFoo
|
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyFoo
|
||||||
|
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||||
@@ -68,9 +66,6 @@ data class Foo(val bar: Int)
|
|||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||||
|
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
|
||||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
|
||||||
|
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||||
// CHECK: ret %struct.ObjHeader*
|
// CHECK: ret %struct.ObjHeader*
|
||||||
|
|
||||||
@@ -78,14 +73,15 @@ fun maybeAnyFoo(maybeAny: Any?, foo: Foo): String {
|
|||||||
return "$maybeAny,$foo"
|
return "$maybeAny,$foo"
|
||||||
}
|
}
|
||||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyMaybeFoo
|
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated#maybeAnyMaybeFoo
|
||||||
|
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String)
|
||||||
|
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||||
|
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_generated.Foo#toString(){}kotlin.String"
|
|
||||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
|
||||||
|
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||||
// CHECK: ret %struct.ObjHeader*
|
// CHECK: ret %struct.ObjHeader*
|
||||||
|
|||||||
+1
-3
@@ -7,11 +7,9 @@ package codegen.stringConcatenationTypeNarrowing.kt53119_append_manual
|
|||||||
import kotlin.test.*
|
import kotlin.test.*
|
||||||
|
|
||||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_manual#appendMaybeAny(kotlin.Any?)
|
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_manual#appendMaybeAny(kotlin.Any?)
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
|
||||||
|
|
||||||
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_manual.Foo#toString(){}kotlin.String"
|
// CHECK: %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_append_manual.Foo#toString(){}kotlin.String"
|
||||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append(kotlin.String?)
|
||||||
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
// CHECK-NOT: %struct.ObjHeader* @"kfun:kotlin.text.StringBuilder#append
|
||||||
|
|
||||||
// CHECK: ret %struct.ObjHeader*
|
// CHECK: ret %struct.ObjHeader*
|
||||||
|
|||||||
+7
-15
@@ -9,17 +9,15 @@ import kotlin.test.*
|
|||||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension#manualPlusExtensionAny
|
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension#manualPlusExtensionAny
|
||||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||||
|
|
||||||
|
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension.Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
|
|
||||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||||
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||||
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
|
||||||
|
|
||||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension.Foo#toString(){}kotlin.String"
|
|
||||||
|
|
||||||
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
||||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
|
||||||
|
|
||||||
// CHECK: ret %struct.ObjHeader*
|
// CHECK: ret %struct.ObjHeader*
|
||||||
|
|
||||||
@@ -43,16 +41,12 @@ fun manualPlusExtensionString(maybeStr: String?, str: String): kotlin.String =
|
|||||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension#generatedPlusExtensionAny
|
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension#generatedPlusExtensionAny
|
||||||
// CHECK-NOT: kfun:kotlin#plus__at__kotlin.String?(kotlin.Any?)
|
// CHECK-NOT: kfun:kotlin#plus__at__kotlin.String?(kotlin.Any?)
|
||||||
|
|
||||||
|
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension.Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||||
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||||
// CHECK-NOT: kfun:kotlin#plus__at__kotlin.String?(kotlin.Any?)
|
// CHECK-NOT: kfun:kotlin#plus__at__kotlin.String?(kotlin.Any?)
|
||||||
|
|
||||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension.Foo#toString(){}kotlin.String"
|
|
||||||
|
|
||||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
|
||||||
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
||||||
// CHECK-NOT: kfun:kotlin#plus__at__kotlin.String?(kotlin.Any?)
|
|
||||||
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
|
||||||
|
|
||||||
// CHECK: ret %struct.ObjHeader*
|
// CHECK: ret %struct.ObjHeader*
|
||||||
|
|
||||||
@@ -98,14 +92,12 @@ fun generatedPlusExtensionFoo(maybeStr: String?, foo: Foo): String {
|
|||||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension#generatedPlusExtensionMaybeFoo
|
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension#generatedPlusExtensionMaybeFoo
|
||||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||||
|
|
||||||
|
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension.Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK-NOT: Foo#toString(){}kotlin.String
|
||||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||||
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
// CHECK-NOT: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||||
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
||||||
|
|
||||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_extension.Foo#toString(){}kotlin.String"
|
|
||||||
// CHECK-NOT: Foo#toString(){}kotlin.String
|
|
||||||
|
|
||||||
// CHECK-NOT: call %struct.ObjHeader* @"kfun:kotlin.String#toString(){}kotlin.String"
|
|
||||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||||
|
|
||||||
// CHECK: ret %struct.ObjHeader*
|
// CHECK: ret %struct.ObjHeader*
|
||||||
|
|||||||
+4
-8
@@ -9,11 +9,9 @@ import kotlin.test.*
|
|||||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member#manualPlusMemberAny
|
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member#manualPlusMemberAny
|
||||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||||
|
|
||||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
|
||||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
|
||||||
|
|
||||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member.Foo#toString(){}kotlin.String"
|
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member.Foo#toString(){}kotlin.String"
|
||||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||||
|
|
||||||
// CHECK: ret %struct.ObjHeader*
|
// CHECK: ret %struct.ObjHeader*
|
||||||
@@ -37,12 +35,9 @@ fun manualPlusMemberString(str1: String, str2: String): kotlin.String =
|
|||||||
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member#generatedPlusMemberAny
|
// CHECK-LABEL: define %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member#generatedPlusMemberAny
|
||||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||||
|
|
||||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
|
||||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
|
||||||
|
|
||||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member.Foo#toString(){}kotlin.String"
|
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member.Foo#toString(){}kotlin.String"
|
||||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
|
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||||
|
|
||||||
// CHECK: ret %struct.ObjHeader*
|
// CHECK: ret %struct.ObjHeader*
|
||||||
@@ -86,9 +81,10 @@ fun manualPlusMemberFoo(str1: String, foo: Foo): kotlin.String =
|
|||||||
// CHECK call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member.Foo#toString(){}kotlin.String"
|
// CHECK call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member.Foo#toString(){}kotlin.String"
|
||||||
// CHECK-NOT Foo#toString(){}kotlin.String
|
// CHECK-NOT Foo#toString(){}kotlin.String
|
||||||
|
|
||||||
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
|
||||||
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member.Foo#toString
|
// CHECK: call %struct.ObjHeader* @"kfun:codegen.stringConcatenationTypeNarrowing.kt53119_plus_member.Foo#toString
|
||||||
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
// CHECK-NOT: kfun:kotlin.String#plus(kotlin.Any?)
|
||||||
|
// CHECK: call %struct.ObjHeader* @Kotlin_String_plusImpl
|
||||||
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
// CHECK-NOT: Foo#toString(){}kotlin.String"
|
||||||
|
|
||||||
// CHECK: ret %struct.ObjHeader*
|
// CHECK: ret %struct.ObjHeader*
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
var i = 1
|
||||||
|
fun main() {
|
||||||
|
println(when(i) {
|
||||||
|
0 -> 10
|
||||||
|
1 -> 11
|
||||||
|
2 -> 12
|
||||||
|
else -> 13
|
||||||
|
})
|
||||||
|
}
|
||||||
|
// CHECK-LABEL: define void @"kfun:#main(){}"()
|
||||||
|
// CHECK: when_case
|
||||||
|
// CHECK: when_next
|
||||||
|
// CHECK: when_case1
|
||||||
|
// CHECK: when_next2
|
||||||
|
// CHECK: when_case3
|
||||||
|
// CHECK: when_next4
|
||||||
|
// CHECK: when_exit
|
||||||
|
// CHECK: call void @"kfun:kotlin.io#println(kotlin.Any?)
|
||||||
|
// CHECK: ret void
|
||||||
Reference in New Issue
Block a user