backend: lower safe casts
This commit is contained in:
committed by
SvyatoslavScherbina
parent
008b8ec031
commit
7b29f4854c
+3
@@ -20,6 +20,9 @@ internal class KonanLower(val context: Context) {
|
||||
phaser.phase(KonanPhase.LOWER_BUILTIN_OPERATORS) {
|
||||
BuiltinOperatorLowering(context).runOnFilePostfix(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_TYPE_OPERATORS) {
|
||||
TypeOperatorLowering(context).runOnFilePostfix(irFile)
|
||||
}
|
||||
phaser.phase(KonanPhase.LOWER_SHARED_VARIABLES) {
|
||||
SharedVariablesLowering(context).runOnFilePostfix(irFile)
|
||||
}
|
||||
|
||||
+1
@@ -9,6 +9,7 @@ enum class KonanPhase(val description: String,
|
||||
/* */ BACKEND("All backend"),
|
||||
/* ... */ LOWER("IR Lowering"),
|
||||
/* ... ... */ LOWER_BUILTIN_OPERATORS("BuiltIn Operators Lowering"),
|
||||
/* ... ... */ LOWER_TYPE_OPERATORS("Type operators lowering"),
|
||||
/* ... ... */ LOWER_SHARED_VARIABLES("Shared Variable Lowering"),
|
||||
/* ... ... */ LOWER_LOCAL_FUNCTIONS("Local Function Lowering"),
|
||||
/* ... ... */ LOWER_CALLABLES("Callable references Lowering"),
|
||||
|
||||
+1
-28
@@ -1323,40 +1323,13 @@ internal class CodeGeneratorVisitor(val context: Context) : IrElementVisitorVoid
|
||||
IrTypeOperator.IMPLICIT_CAST -> return evaluateExpression(value.argument)
|
||||
IrTypeOperator.IMPLICIT_NOTNULL -> TODO("${ir2string(value)}")
|
||||
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT -> return evaluateExpression(value.argument)
|
||||
IrTypeOperator.SAFE_CAST -> return evaluateSafeCast(value)
|
||||
IrTypeOperator.SAFE_CAST -> throw IllegalStateException("safe cast wasn't lowered")
|
||||
IrTypeOperator.INSTANCEOF -> return evaluateInstanceOf(value)
|
||||
IrTypeOperator.NOT_INSTANCEOF -> return evaluateNotInstanceOf(value)
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
|
||||
private fun evaluateSafeCast(value: IrTypeOperatorCall): LLVMValueRef? {
|
||||
val bbTrue = codegen.basicBlock()
|
||||
val bbFalse = codegen.basicBlock()
|
||||
val bbExit = codegen.basicBlock()
|
||||
|
||||
val resultLlvmType = codegen.getLLVMType(value.type)
|
||||
val result = codegen.vars.createAnonymousMutable(resultLlvmType)
|
||||
|
||||
val condition = evaluateInstanceOf(value)
|
||||
codegen.condBr(condition, bbTrue, bbFalse)
|
||||
|
||||
codegen.positionAtEnd(bbTrue)
|
||||
val castResult = evaluateExpression(value.argument)
|
||||
codegen.vars.store(castResult!!, result)
|
||||
codegen.br(bbExit)
|
||||
|
||||
codegen.positionAtEnd(bbFalse)
|
||||
val nullResult = LLVMConstNull(resultLlvmType)!!
|
||||
codegen.vars.store(nullResult, result)
|
||||
codegen.br(bbExit)
|
||||
|
||||
codegen.positionAtEnd(bbExit)
|
||||
return codegen.vars.load(result)
|
||||
}
|
||||
|
||||
//-------------------------------------------------------------------------//
|
||||
// table of conversion with llvm for primitive types
|
||||
// to be used in replacement fo primitive.toX() calls with
|
||||
|
||||
+56
@@ -0,0 +1,56 @@
|
||||
package org.jetbrains.kotlin.backend.konan.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.FunctionLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.lower.createFunctionIrGenerator
|
||||
import org.jetbrains.kotlin.backend.common.lower.irBlock
|
||||
import org.jetbrains.kotlin.backend.konan.Context
|
||||
import org.jetbrains.kotlin.descriptors.FunctionDescriptor
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFunction
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
|
||||
import org.jetbrains.kotlin.ir.expressions.IrTypeOperatorCall
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
/**
|
||||
* This lowering pass lowers some [IrTypeOperatorCall]s.
|
||||
*/
|
||||
internal class TypeOperatorLowering(val context: Context) : FunctionLoweringPass {
|
||||
override fun lower(irFunction: IrFunction) {
|
||||
val transformer = TypeOperatorTransformer(context, irFunction.descriptor)
|
||||
irFunction.transformChildrenVoid(transformer)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class TypeOperatorTransformer(val context: Context, val function: FunctionDescriptor) : IrElementTransformerVoid() {
|
||||
|
||||
private val generator = context.createFunctionIrGenerator(function)
|
||||
|
||||
override fun visitFunction(declaration: IrFunction): IrStatement {
|
||||
// ignore inner functions during this pass
|
||||
return declaration
|
||||
}
|
||||
|
||||
private fun lowerSafeCast(expression: IrTypeOperatorCall): IrExpression {
|
||||
return generator.irBlock(expression) {
|
||||
+irLet(expression.argument) { variable ->
|
||||
irIfThenElse(expression.type,
|
||||
condition = irIs(irGet(variable), expression.typeOperand),
|
||||
thenPart = irImplicitCast(irGet(variable), expression.typeOperand),
|
||||
elsePart = irNull())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall): IrExpression {
|
||||
expression.transformChildrenVoid(this)
|
||||
|
||||
return when (expression.operator) {
|
||||
IrTypeOperator.SAFE_CAST -> lowerSafeCast(expression)
|
||||
else -> expression
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user