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 2497f5ac878..76d7beedd2b 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 @@ -1108,43 +1108,69 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map functionGenerationContext.theUnitInstanceRef.llvm - isNothing -> functionGenerationContext.kNothingFakeValue - !coverAllCases -> LLVMGetUndef(llvmType)!! - else -> resultPhi!! } } + private fun evaluateWhen(expression: IrWhen): LLVMValueRef { + context.log{"evaluateWhen : ${ir2string(expression)}"} + + val whenEmittingContext = WhenEmittingContext(expression) + + expression.branches.forEach { + val bbNext = if (it == expression.branches.last()) + null + else + functionGenerationContext.basicBlock("when_next", it.startLocation) + generateWhenCase(whenEmittingContext, it, bbNext) + } + + if (whenEmittingContext.bbExit.isInitialized()) + functionGenerationContext.positionAtEnd(whenEmittingContext.bbExit.value) + + return when { + expression.type.isUnit() -> functionGenerationContext.theUnitInstanceRef.llvm + expression.type.isNothing() -> functionGenerationContext.kNothingFakeValue + whenEmittingContext.resultPhi.isInitialized() -> whenEmittingContext.resultPhi.value + else -> LLVMGetUndef(whenEmittingContext.llvmType)!! + } + } + + private fun generateWhenCase(whenEmittingContext: WhenEmittingContext, branch: IrBranch, bbNext: LLVMBasicBlockRef?) { + val brResult = if (isUnconditional(branch)) + evaluateExpression(branch.result) + else { + val bbCase = functionGenerationContext.basicBlock("when_case", branch.startLocation) + val condition = evaluateExpression(branch.condition) + functionGenerationContext.condBr(condition, bbCase, bbNext ?: whenEmittingContext.bbExit.value) + functionGenerationContext.positionAtEnd(bbCase) + evaluateExpression(branch.result) + } + if (!functionGenerationContext.isAfterTerminator()) { + if (whenEmittingContext.needsPhi) + functionGenerationContext.assignPhis(whenEmittingContext.resultPhi.value to brResult) + functionGenerationContext.br(whenEmittingContext.bbExit.value) + } + if (bbNext != null) + functionGenerationContext.positionAtEnd(bbNext) + } + + //-------------------------------------------------------------------------// + // Checks if the branch is unconditional + + private fun isUnconditional(branch: IrBranch): Boolean = + branch.condition is IrConst<*> // If branch condition is constant. + && (branch.condition as IrConst<*>).value as Boolean // If condition is "true" + //-------------------------------------------------------------------------// private fun evaluateWhileLoop(loop: IrWhileLoop): LLVMValueRef { @@ -2502,41 +2528,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map // If branch condition is constant. - && (branch.condition as IrConst<*>).value as Boolean // If condition is "true" - - //-------------------------------------------------------------------------// - fun callDirect(descriptor: FunctionDescriptor, args: List, resultLifetime: Lifetime): LLVMValueRef { val realDescriptor = descriptor.target