[JS IR BE] Right support for inc and dec on primitive numbers

This commit is contained in:
Zalim Bashorov
2018-04-25 23:38:57 +03:00
parent 6725f085c7
commit 5c40892c57
6 changed files with 37 additions and 20 deletions
@@ -9,7 +9,7 @@ import com.intellij.openapi.project.Project
import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.common.runOnFilePostfix
import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.ir.backend.js.lower.IntrinsicifyBuiltinOperationsLowering
import org.jetbrains.kotlin.ir.backend.js.lower.IntrinsicifyCallsLowering
import org.jetbrains.kotlin.ir.backend.js.lower.SecondaryCtorLowering
import org.jetbrains.kotlin.ir.backend.js.transformers.irToJs.IrModuleToJsTransformer
import org.jetbrains.kotlin.ir.declarations.IrFile
@@ -62,5 +62,5 @@ fun JsIrBackendContext.lower(file: IrFile) {
InitializersLowering(this, JsLoweredDeclarationOrigin.CLASS_STATIC_INITIALIZER, false).runOnFilePostfix(file)
SecondaryCtorLowering(this).lower(file)
IntrinsicifyBuiltinOperationsLowering(this).lower(file)
IntrinsicifyCallsLowering(this).lower(file)
}
@@ -6,15 +6,18 @@
package org.jetbrains.kotlin.ir.backend.js.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
import org.jetbrains.kotlin.ir.backend.js.utils.name
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrConstKind
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.copyTypeArgumentsFrom
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.name.Name
@@ -22,27 +25,25 @@ import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.SimpleType
import org.jetbrains.kotlin.util.OperatorNameConventions
class IntrinsicifyBuiltinOperationsLowering(private val context: JsIrBackendContext) : FileLoweringPass {
class IntrinsicifyCallsLowering(private val context: JsIrBackendContext) : FileLoweringPass {
// TODO: should/can we unify these maps?
private val primitiveNumberIntrinsics: Map<SimpleMemberKey, IrSimpleFunction>
private val comparisonIntrinsics: Map<IrFunctionSymbol, IrSimpleFunction>
private val memberToTransformer: Map<SimpleMemberKey, (IrCall) -> IrCall>
private val memberToIrFunction: Map<SimpleMemberKey, IrSimpleFunction>
private val symbolToIrFunction: Map<IrFunctionSymbol, IrSimpleFunction>
init {
primitiveNumberIntrinsics = mutableMapOf()
comparisonIntrinsics = mutableMapOf()
memberToIrFunction = mutableMapOf()
symbolToIrFunction = mutableMapOf()
memberToTransformer = mutableMapOf()
primitiveNumberIntrinsics.run {
val primitiveNumbers = context.irBuiltIns.run { listOf(int, short, byte, float, double) }
val primitiveNumbers = context.irBuiltIns.run { listOf(int, short, byte, float, double) }
memberToIrFunction.run {
for (type in primitiveNumbers) {
op(type, OperatorNameConventions.UNARY_PLUS, context.intrinsics.jsUnaryPlus)
op(type, OperatorNameConventions.UNARY_MINUS, context.intrinsics.jsUnaryMinus)
// TODO: inc & dec are mapped wrongly
op(type, OperatorNameConventions.INC, context.intrinsics.jsPrefixInc)
op(type, OperatorNameConventions.DEC, context.intrinsics.jsPrefixDec)
op(type, OperatorNameConventions.PLUS, context.intrinsics.jsPlus)
op(type, OperatorNameConventions.MINUS, context.intrinsics.jsMinus)
op(type, OperatorNameConventions.TIMES, context.intrinsics.jsMult)
@@ -69,7 +70,7 @@ class IntrinsicifyBuiltinOperationsLowering(private val context: JsIrBackendCont
}
}
comparisonIntrinsics.run {
symbolToIrFunction.run {
add(context.irBuiltIns.eqeqeqSymbol, context.intrinsics.jsEqeqeq)
// TODO: implement it a right way
add(context.irBuiltIns.eqeqSymbol, context.intrinsics.jsEqeq)
@@ -83,6 +84,22 @@ class IntrinsicifyBuiltinOperationsLowering(private val context: JsIrBackendCont
add(context.irBuiltIns.greaterFunByOperandType, context.intrinsics.jsGt)
add(context.irBuiltIns.greaterOrEqualFunByOperandType, context.intrinsics.jsGtEq)
}
memberToTransformer.run {
for (type in primitiveNumbers) {
// TODO: use increment and decrement when it's possible
op(type, OperatorNameConventions.INC) {
irCall(it, context.intrinsics.jsPlus.symbol, dispatchReceiverAsFirstArgument = true).apply {
putValueArgument(1, IrConstImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.int, IrConstKind.Int, 1))
}
}
op(type, OperatorNameConventions.DEC) {
irCall(it, context.intrinsics.jsMinus.symbol, dispatchReceiverAsFirstArgument = true).apply {
putValueArgument(1, IrConstImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, context.irBuiltIns.int, IrConstKind.Int, 1))
}
}
}
}
}
override fun lower(irFile: IrFile) {
@@ -93,17 +110,21 @@ class IntrinsicifyBuiltinOperationsLowering(private val context: JsIrBackendCont
if (call is IrCall) {
val symbol = call.symbol
comparisonIntrinsics[symbol]?.let {
symbolToIrFunction[symbol]?.let {
return irCall(call, it.symbol)
}
(symbol.owner as? IrFunction)?.dispatchReceiverParameter?.let {
val key = SimpleMemberKey(it.type, symbol.name)
primitiveNumberIntrinsics[key]?.let {
memberToIrFunction[key]?.let {
// TODO: don't apply intrinsics when type of receiver or argument is Long
return irCall(call, it.symbol, dispatchReceiverAsFirstArgument = true)
}
memberToTransformer[key]?.let {
return it(call)
}
}
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1110
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1122
package foo
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1121
package foo
-1
View File
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JS_IR
// EXPECTED_REACHABLE_NODES: 1112
package foo