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 {
|
||||
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
|
||||
|
||||
@@ -811,7 +811,6 @@ class JvmSymbols(
|
||||
addFunction("equals", irBuiltIns.booleanType, isStatic = true).apply {
|
||||
addValueParameter("a", arrayType)
|
||||
addValueParameter("b", arrayType)
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -856,6 +855,19 @@ class JvmSymbols(
|
||||
val remainderUnsignedLong: IrSimpleFunctionSymbol = javaLangLong.functionByName("remainderUnsigned")
|
||||
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 ->
|
||||
klass.addFunction("compareUnsigned", irBuiltIns.intType, isStatic = true).apply {
|
||||
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.throwUnsupportedOperationException.toKey()!! to ThrowException(Type.getObjectType("java/lang/UnsupportedOperationException")),
|
||||
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() +
|
||||
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.util.*
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
internal val jvmOptimizationLoweringPhase = makeIrFilePhase(
|
||||
::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)
|
||||
removeUnnecessaryTemporaryVariables(expression.statements)
|
||||
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 {
|
||||
// Replace IrGetValue of an immutable temporary variable with a constant
|
||||
// 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 {
|
||||
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
|
||||
|
||||
+6
@@ -3941,6 +3941,12 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
||||
public void testJavaPrimitiveType() throws Exception {
|
||||
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
|
||||
|
||||
Reference in New Issue
Block a user