diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt index 46645dc42dc..6ebdb686399 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/IrUtils.kt @@ -19,6 +19,7 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.descriptors.* import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl import org.jetbrains.kotlin.ir.expressions.impl.IrInstanceInitializerCallImpl import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy @@ -694,4 +695,10 @@ fun IrExpression?.isPure( } return false -} \ No newline at end of file +} + +fun IrExpression.isTrivial() = + this is IrConst<*> || + this is IrGetValue || + this is IrGetObjectValue || + this is IrErrorExpressionImpl \ No newline at end of file diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/IfNullExpressionsFusionLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/IfNullExpressionsFusionLowering.kt index 8f48c790cc4..0bf77f8637d 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/IfNullExpressionsFusionLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/IfNullExpressionsFusionLowering.kt @@ -7,6 +7,8 @@ package org.jetbrains.kotlin.backend.common.lower import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.ir.isTrivial +import org.jetbrains.kotlin.backend.common.lower.loops.canHaveSideEffects import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.ir.builders.createTmpVariable import org.jetbrains.kotlin.ir.builders.irBlock @@ -14,11 +16,13 @@ import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.builders.irIfNull import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* +import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.isNullable import org.jetbrains.kotlin.ir.util.fileOrNull +import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid @@ -189,11 +193,13 @@ class IfNullExpressionsFusionLowering(val context: CommonBackendContext) : FileL null } - private fun IrExpression.isTrivial() = - this is IrExpressionWithCopy - private fun IrExpression.copyIfTrivial() = - if (this is IrExpressionWithCopy) copy() else this + if (isTrivial()) { + require(this is IrExpressionWithCopy) { + "Not a copyable expression: ${render()}" + } + copy() + } else this private fun IrExpression.remap(from: IrVariable, to: Lazy): IrExpression = copyIfTrivial().transform(object : AbstractVariableRemapper() { diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt index 83f38b6f83e..97a4cef914e 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/Utils.kt @@ -5,6 +5,7 @@ package org.jetbrains.kotlin.backend.common.lower.loops +import org.jetbrains.kotlin.backend.common.ir.isTrivial import org.jetbrains.kotlin.backend.common.lower.DeclarationIrBuilder import org.jetbrains.kotlin.ir.builders.createTmpVariable import org.jetbrains.kotlin.ir.builders.irGet @@ -13,11 +14,13 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl +import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.getClass import org.jetbrains.kotlin.ir.types.isNothing import org.jetbrains.kotlin.ir.util.defaultType import org.jetbrains.kotlin.ir.util.functions +import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.util.OperatorNameConventions @@ -70,7 +73,7 @@ internal fun IrExpression.decrement(): IrExpression { } internal val IrExpression.canHaveSideEffects: Boolean - get() = this !is IrExpressionWithCopy + get() = !isTrivial() private fun Any?.toLong(): Long? = when (this) { @@ -95,9 +98,12 @@ internal fun DeclarationIrBuilder.createTemporaryVariableIfNecessary( expression: IrExpression, nameHint: String? = null, irType: IrType? = null, isMutable: Boolean = false ): Pair = - if (expression !is IrExpressionWithCopy) { + if (expression.canHaveSideEffects) { scope.createTmpVariable(expression, nameHint = nameHint, irType = irType, isMutable = isMutable).let { Pair(it, irGet(it)) } } else { + require(expression is IrExpressionWithCopy) { + "Not a copyable expression: ${expression.render()}" + } Pair(null, expression) }