From 8fbc06809ad42474ffda884d852212699296b8ba Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Thu, 4 May 2017 14:16:58 +0500 Subject: [PATCH] Codegen: optimization of `catch (t: Throwable) {}` --- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 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 99cacf6d258..39d51b96720 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 @@ -885,21 +885,31 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid private val success: ContinuationBlock) : CatchingScope() { override fun genHandler(exception: LLVMValueRef) { - // TODO: optimize for `Throwable` clause. - catches.forEach { - val isInstance = genInstanceOf(exception, it.parameter.type) - val nextCheck = codegen.basicBlock("catchCheck") - val body = codegen.basicBlock("catch") - codegen.condBr(isInstance, body, nextCheck) - codegen.appendingTo(body) { + for (catch in catches) { + fun genCatchBlock() { using(VariableScope()) { - currentCodeContext.genDeclareVariable(it.parameter, exception) - evaluateExpressionAndJump(it.result, success) + currentCodeContext.genDeclareVariable(catch.parameter, exception) + evaluateExpressionAndJump(catch.result, success) } } - codegen.positionAtEnd(nextCheck) + if (catch.parameter.type == context.builtIns.throwable.defaultType) { + genCatchBlock() + return // Remaining catch clauses are unreachable. + } else { + val isInstance = genInstanceOf(exception, catch.parameter.type) + val body = codegen.basicBlock("catch") + val nextCheck = codegen.basicBlock("catchCheck") + codegen.condBr(isInstance, body, nextCheck) + + codegen.appendingTo(body) { + genCatchBlock() + } + + codegen.positionAtEnd(nextCheck) + + } } // rethrow the exception if no clause can handle it. outerContext.genThrow(exception)