From 667b5fb936be1e1d34daa3f993ecd1d214181c5c Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Wed, 3 May 2017 13:41:42 +0500 Subject: [PATCH] Removed finally blocks handling from code generator --- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 146 ++---------------- 1 file changed, 11 insertions(+), 135 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 dfa523456d1..6e0a18c9229 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 @@ -906,148 +906,24 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid } } - /** - * The [InnerScope] that includes code generated by [genFinalizeImpl] when leaving it - * with `return`, `break`, `continue` or throwing exception. - */ - private abstract inner class FinalizingScope() : CatchingScope() { - - /** - * Cache for [genReturn]. - * - * `returnBlocks[func]` contains the [ContinuationBlock] to be used for `return` from `func`; - * the block expects return value as its value. - */ - private val returnBlocks = mutableMapOf() - - // Jump to finalize-and-return instead of simply returning. - override fun genReturn(target: CallableDescriptor, value: LLVMValueRef?) { - val block = returnBlocks.getOrPut(target) { - continuationBlock(target.returnType!!) { - genFinalize() - val returnValue = it.valuePhi // `null` if return type is `Unit`. - outerContext.genReturn(target, returnValue) - } - } - - jump(block, value) - } - - /** - * Cache for [genBreak]. - */ - private val breakBlocks = mutableMapOf() - - // Jump to finalize-and-break instead of simply breaking. - override fun genBreak(destination: IrBreak) { - val block = breakBlocks.getOrPut(destination.loop) { - codegen.basicBlock("finalizeAndBreak") { - genFinalize() - outerContext.genBreak(destination) - } - } - - codegen.br(block) - } - - /** - * Cache for [genContinue]. - * - * Note: can't merge with [breakBlocks] because the code for `break` and `continue` is different. - */ - private val continueBlocks = mutableMapOf() - - // Jump to finalize-and-continue instead of simply continuing. - override fun genContinue(destination: IrContinue) { - val block = continueBlocks.getOrPut(destination.loop) { - codegen.basicBlock("finalizeAndContinue") { - genFinalize() - outerContext.genContinue(destination) - } - } - - codegen.br(block) - } - - // When an exception is caught, finalize the scope and rethrow the exception. - override fun genHandler(exception: LLVMValueRef) { - genFinalizeImpl() - outerContext.genThrow(exception) - } - - private fun genFinalize() { - using(outerContext) { - this.genFinalizeImpl() - } - } - - protected abstract fun genFinalizeImpl() - } - - /** - * Generates the code which gets "finalized" exactly once when completed either normally or abnormally. - * - * @param code generates the code to be post-dominated by cleanup. - * It must jump to given [ContinuationBlock] with its result when completed normally. - * - * @param finalize generates the cleanup code that must be executed when code generated by [code] is completed. - * - * @param type Kotlin type of the result of generated code. - * - * @return the result of the generated code. - */ - private fun genFinalizedBy(finalize: (() -> Unit)?, - type: KotlinType, code: (ContinuationBlock) -> Unit): LLVMValueRef { - - val scope = if (finalize == null) null else { - object : FinalizingScope() { - override fun genFinalizeImpl() { - finalize() - } - } - } - - val continuation = continuationBlock(type) - - using(scope) { - code(continuation) - } - codegen.positionAtEnd(continuation.block) - finalize?.invoke() - - // TODO: finalize is duplicated many times (just as in C++, Java or Kotlin JVM); - // it is very important to optimize this. - - return continuation.value - } - - /** - * Generates code that is "finalized" by given expression. - */ - private fun genFinalizedBy(finalize: IrExpression?, type: KotlinType, - code: (ContinuationBlock) -> Unit): LLVMValueRef { - - val finalizeFun: (() -> Unit)? = if (finalize == null) { - null - } else { - { evaluateExpression(finalize) } - } - - return genFinalizedBy(finalizeFun, type, code) - } - private fun evaluateTry(expression: IrTry): LLVMValueRef { // TODO: does basic block order influence machine code order? // If so, consider reordering blocks to reduce exception tables size. - return genFinalizedBy(expression.finallyExpression, expression.type) { continuation -> + assert (expression.finallyExpression == null, { "All finally blocks should've been lowered" }) - val catchScope = if (expression.catches.isEmpty()) null else CatchScope(expression.catches, continuation) + val continuation = continuationBlock(expression.type) - using(catchScope) { - evaluateExpressionAndJump(expression.tryResult, continuation) - } + val catchScope = if (expression.catches.isEmpty()) + null + else + CatchScope(expression.catches, continuation) + using(catchScope) { + evaluateExpressionAndJump(expression.tryResult, continuation) } + codegen.positionAtEnd(continuation.block) + + return continuation.value } //-------------------------------------------------------------------------//