JVM_IR KT-42010 use IINC for postfix int increment/decrement
This commit is contained in:
+6
@@ -3941,6 +3941,12 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
|||||||
public void testJavaPrimitiveType() throws Exception {
|
public void testJavaPrimitiveType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/intrinsics/javaPrimitiveType.kt");
|
runTest("compiler/testData/codegen/bytecodeText/intrinsics/javaPrimitiveType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("postfixIncrDecr.kt")
|
||||||
|
public void testPostfixIncrDecr() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/intrinsics/postfixIncrDecr.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
@@ -811,7 +811,6 @@ class JvmSymbols(
|
|||||||
addFunction("equals", irBuiltIns.booleanType, isStatic = true).apply {
|
addFunction("equals", irBuiltIns.booleanType, isStatic = true).apply {
|
||||||
addValueParameter("a", arrayType)
|
addValueParameter("a", arrayType)
|
||||||
addValueParameter("b", arrayType)
|
addValueParameter("b", arrayType)
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -856,6 +855,19 @@ class JvmSymbols(
|
|||||||
val remainderUnsignedLong: IrSimpleFunctionSymbol = javaLangLong.functionByName("remainderUnsigned")
|
val remainderUnsignedLong: IrSimpleFunctionSymbol = javaLangLong.functionByName("remainderUnsigned")
|
||||||
val toUnsignedStringLong: IrSimpleFunctionSymbol = javaLangLong.functionByName("toUnsignedString")
|
val toUnsignedStringLong: IrSimpleFunctionSymbol = javaLangLong.functionByName("toUnsignedString")
|
||||||
|
|
||||||
|
val intPostfixIncr = createPostfixIncrDecrFun("<int++>", irBuiltIns.intType)
|
||||||
|
val intPostfixDecr = createPostfixIncrDecrFun("<int-->", irBuiltIns.intType)
|
||||||
|
|
||||||
|
private fun createPostfixIncrDecrFun(intrinsicName: String, type: IrType): IrSimpleFunctionSymbol =
|
||||||
|
irFactory.buildFun {
|
||||||
|
name = Name.special(intrinsicName)
|
||||||
|
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
|
||||||
|
}.apply {
|
||||||
|
parent = kotlinJvmInternalPackage
|
||||||
|
addValueParameter("value", type)
|
||||||
|
returnType = type
|
||||||
|
}.symbol
|
||||||
|
|
||||||
private fun createJavaPrimitiveClass(fqName: FqName, type: IrType): IrClassSymbol = createClass(fqName) { klass ->
|
private fun createJavaPrimitiveClass(fqName: FqName, type: IrType): IrClassSymbol = createClass(fqName) { klass ->
|
||||||
klass.addFunction("compareUnsigned", irBuiltIns.intType, isStatic = true).apply {
|
klass.addFunction("compareUnsigned", irBuiltIns.intType, isStatic = true).apply {
|
||||||
addValueParameter("x", type)
|
addValueParameter("x", type)
|
||||||
|
|||||||
+3
-1
@@ -87,7 +87,9 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) {
|
|||||||
symbols.throwTypeCastException.toKey()!! to ThrowException(Type.getObjectType("kotlin/TypeCastException")),
|
symbols.throwTypeCastException.toKey()!! to ThrowException(Type.getObjectType("kotlin/TypeCastException")),
|
||||||
symbols.throwUnsupportedOperationException.toKey()!! to ThrowException(Type.getObjectType("java/lang/UnsupportedOperationException")),
|
symbols.throwUnsupportedOperationException.toKey()!! to ThrowException(Type.getObjectType("java/lang/UnsupportedOperationException")),
|
||||||
symbols.throwKotlinNothingValueException.toKey()!! to ThrowKotlinNothingValueException,
|
symbols.throwKotlinNothingValueException.toKey()!! to ThrowKotlinNothingValueException,
|
||||||
symbols.jvmIndyIntrinsic.toKey()!! to JvmInvokeDynamic
|
symbols.jvmIndyIntrinsic.toKey()!! to JvmInvokeDynamic,
|
||||||
|
symbols.intPostfixIncr.toKey()!! to PostfixIinc(1),
|
||||||
|
symbols.intPostfixDecr.toKey()!! to PostfixIinc(-1)
|
||||||
) +
|
) +
|
||||||
numberConversionMethods() +
|
numberConversionMethods() +
|
||||||
unaryFunForPrimitives("plus", UnaryPlus) +
|
unaryFunForPrimitives("plus", UnaryPlus) +
|
||||||
|
|||||||
+26
@@ -0,0 +1,26 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.jvm.codegen.*
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrGetValue
|
||||||
|
import org.jetbrains.kotlin.ir.util.dump
|
||||||
|
import org.jetbrains.kotlin.ir.util.render
|
||||||
|
import org.jetbrains.org.objectweb.asm.Type
|
||||||
|
|
||||||
|
class PostfixIinc(private val delta: Int) : IntrinsicMethod() {
|
||||||
|
override fun invoke(expression: IrFunctionAccessExpression, codegen: ExpressionCodegen, data: BlockInfo): PromisedValue? {
|
||||||
|
val argument = expression.getValueArgument(0) as? IrGetValue
|
||||||
|
?: error("IrGetValue expected: ${expression.dump()}")
|
||||||
|
val varIndex = codegen.frameMap.getIndex(argument.symbol)
|
||||||
|
if (varIndex == -1)
|
||||||
|
error("Unmapped variable: ${argument.render()}")
|
||||||
|
argument.accept(codegen, data).materialize()
|
||||||
|
codegen.mv.iinc(varIndex, delta)
|
||||||
|
return MaterialValue(codegen, Type.INT_TYPE, argument.type)
|
||||||
|
}
|
||||||
|
}
|
||||||
+37
@@ -25,6 +25,7 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrPublicSymbolBase
|
|||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
internal val jvmOptimizationLoweringPhase = makeIrFilePhase(
|
internal val jvmOptimizationLoweringPhase = makeIrFilePhase(
|
||||||
::JvmOptimizationLowering,
|
::JvmOptimizationLowering,
|
||||||
@@ -405,11 +406,47 @@ class JvmOptimizationLowering(val context: JvmBackendContext) : FileLoweringPass
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (expression.origin == IrStatementOrigin.POSTFIX_DECR || expression.origin == IrStatementOrigin.POSTFIX_INCR) {
|
||||||
|
expression.rewritePostfixIncrDecr()?.let { return it }
|
||||||
|
}
|
||||||
|
|
||||||
expression.transformChildren(this, data)
|
expression.transformChildren(this, data)
|
||||||
removeUnnecessaryTemporaryVariables(expression.statements)
|
removeUnnecessaryTemporaryVariables(expression.statements)
|
||||||
return expression
|
return expression
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private fun IrContainerExpression.rewritePostfixIncrDecr(): IrCall? {
|
||||||
|
return when (origin) {
|
||||||
|
IrStatementOrigin.POSTFIX_INCR, IrStatementOrigin.POSTFIX_DECR -> {
|
||||||
|
val tmpVar = this.statements[0] as? IrVariable ?: return null
|
||||||
|
val getIncrVar = tmpVar.initializer as? IrGetValue ?: return null
|
||||||
|
if (!getIncrVar.type.isInt()) return null
|
||||||
|
|
||||||
|
val setVar = this.statements[1] as? IrSetValue ?: return null
|
||||||
|
if (setVar.symbol != getIncrVar.symbol) return null
|
||||||
|
val setVarValue = setVar.value as? IrCall ?: return null
|
||||||
|
val calleeName = setVarValue.symbol.owner.name
|
||||||
|
if (calleeName != OperatorNameConventions.INC && calleeName != OperatorNameConventions.DEC) return null
|
||||||
|
val calleeArg = setVarValue.dispatchReceiver as? IrGetValue ?: return null
|
||||||
|
if (calleeArg.symbol != tmpVar.symbol) return null
|
||||||
|
|
||||||
|
val getTmpVar = this.statements[2] as? IrGetValue ?: return null
|
||||||
|
if (getTmpVar.symbol != tmpVar.symbol) return null
|
||||||
|
|
||||||
|
val intrinsicSymbol =
|
||||||
|
if (calleeName == OperatorNameConventions.INC)
|
||||||
|
context.ir.symbols.intPostfixIncr
|
||||||
|
else
|
||||||
|
context.ir.symbols.intPostfixDecr
|
||||||
|
|
||||||
|
return IrCallImpl.fromSymbolOwner(this.startOffset, this.endOffset, intrinsicSymbol)
|
||||||
|
.apply { putValueArgument(0, getIncrVar) }
|
||||||
|
}
|
||||||
|
else ->
|
||||||
|
null
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue, data: IrClass?): IrExpression {
|
override fun visitGetValue(expression: IrGetValue, data: IrClass?): IrExpression {
|
||||||
// Replace IrGetValue of an immutable temporary variable with a constant
|
// Replace IrGetValue of an immutable temporary variable with a constant
|
||||||
// initializer with the constant initializer.
|
// initializer with the constant initializer.
|
||||||
|
|||||||
@@ -0,0 +1,34 @@
|
|||||||
|
// IGNORE_BACKEND_FIR: JVM_IR
|
||||||
|
|
||||||
|
fun use(i: Int) {}
|
||||||
|
|
||||||
|
fun testPostfixIncr0() {
|
||||||
|
var k = 0
|
||||||
|
k++
|
||||||
|
use(k)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPostfixIncr1() {
|
||||||
|
var k = 0
|
||||||
|
val t = k++
|
||||||
|
use(k)
|
||||||
|
use(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPostfixDecr0() {
|
||||||
|
var k = 0
|
||||||
|
k--
|
||||||
|
use(k)
|
||||||
|
}
|
||||||
|
|
||||||
|
fun testPostfixDecr1() {
|
||||||
|
var k = 0
|
||||||
|
val t = k--
|
||||||
|
use(k)
|
||||||
|
use(t)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 6 ISTORE
|
||||||
|
// 8 ILOAD
|
||||||
|
// 0 ICONST_1
|
||||||
|
// 4 IINC
|
||||||
+6
@@ -3797,6 +3797,12 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
|||||||
public void testJavaPrimitiveType() throws Exception {
|
public void testJavaPrimitiveType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/intrinsics/javaPrimitiveType.kt");
|
runTest("compiler/testData/codegen/bytecodeText/intrinsics/javaPrimitiveType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("postfixIncrDecr.kt")
|
||||||
|
public void testPostfixIncrDecr() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/intrinsics/postfixIncrDecr.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
+6
@@ -3941,6 +3941,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
|||||||
public void testJavaPrimitiveType() throws Exception {
|
public void testJavaPrimitiveType() throws Exception {
|
||||||
runTest("compiler/testData/codegen/bytecodeText/intrinsics/javaPrimitiveType.kt");
|
runTest("compiler/testData/codegen/bytecodeText/intrinsics/javaPrimitiveType.kt");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestMetadata("postfixIncrDecr.kt")
|
||||||
|
public void testPostfixIncrDecr() throws Exception {
|
||||||
|
runTest("compiler/testData/codegen/bytecodeText/intrinsics/postfixIncrDecr.kt");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Nested
|
@Nested
|
||||||
|
|||||||
Reference in New Issue
Block a user