[IR] canHaveSideEffects more robust

By default copyable (IrExpressionWithCopy) declarations is considered as side-effects.

^KT-45655 fixed

[IR] isTrivial more robust

By default copyable (IrExpressionWithCopy) declarations is considered as trivials.

[IR] Use one source of truth for triviality of IrExpression
This commit is contained in:
Ilya Goncharov
2021-03-24 16:00:24 +03:00
committed by TeamCityServer
parent 47f1a8a0bb
commit 7046f9badd
3 changed files with 26 additions and 7 deletions
@@ -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
}
}
fun IrExpression.isTrivial() =
this is IrConst<*> ||
this is IrGetValue ||
this is IrGetObjectValue ||
this is IrErrorExpressionImpl
@@ -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<IrVariable>): IrExpression =
copyIfTrivial().transform(object : AbstractVariableRemapper() {
@@ -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<IrVariable?, IrExpressionWithCopy> =
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)
}