[IR] Remove IrExpressionWithCopy and replace with shallowCopy method
This commit is contained in:
committed by
TeamCityServer
parent
084d824984
commit
368ac36204
@@ -18,10 +18,7 @@ import org.jetbrains.kotlin.ir.builders.declarations.buildTypeParameter
|
||||
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.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.overrides.FakeOverrideBuilderStrategy
|
||||
import org.jetbrains.kotlin.ir.overrides.IrOverridingUtil
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
@@ -695,10 +692,4 @@ fun IrExpression?.isPure(
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
fun IrExpression.isTrivial() =
|
||||
this is IrConst<*> ||
|
||||
this is IrGetValue ||
|
||||
this is IrGetObjectValue ||
|
||||
this is IrErrorExpressionImpl
|
||||
}
|
||||
+3
-8
@@ -7,8 +7,6 @@ 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
|
||||
@@ -16,13 +14,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.util.isTrivial
|
||||
import org.jetbrains.kotlin.ir.util.shallowCopy
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
|
||||
@@ -195,10 +193,7 @@ class IfNullExpressionsFusionLowering(val context: CommonBackendContext) : FileL
|
||||
|
||||
private fun IrExpression.copyIfTrivial() =
|
||||
if (isTrivial()) {
|
||||
require(this is IrExpressionWithCopy) {
|
||||
"Not a copyable expression: ${render()}"
|
||||
}
|
||||
copy()
|
||||
shallowCopy()
|
||||
} else this
|
||||
|
||||
private fun IrExpression.remap(from: IrVariable, to: Lazy<IrVariable>): IrExpression =
|
||||
|
||||
+9
-8
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.ir.types.*
|
||||
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.ir.util.shallowCopy
|
||||
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
@@ -262,20 +263,20 @@ private class Transformer(
|
||||
additionalStatements.addIfNotNull(lowerVar)
|
||||
additionalStatements.addIfNotNull(upperVar)
|
||||
}
|
||||
lowerExpression = tmpLowerExpression.copy()
|
||||
upperExpression = tmpUpperExpression.copy()
|
||||
lowerExpression = tmpLowerExpression.shallowCopy()
|
||||
upperExpression = tmpUpperExpression.shallowCopy()
|
||||
useLowerClauseOnLeftSide = true
|
||||
} else if (lower.canHaveSideEffects && upper.canHaveSideEffects) {
|
||||
if (shouldUpperComeFirst) {
|
||||
val (upperVar, tmpUpperExpression) = createTemporaryVariableIfNecessary(upper, "containsUpper")
|
||||
additionalStatements.add(upperVar!!)
|
||||
lowerExpression = lower
|
||||
upperExpression = tmpUpperExpression.copy()
|
||||
upperExpression = tmpUpperExpression.shallowCopy()
|
||||
useLowerClauseOnLeftSide = true
|
||||
} else {
|
||||
val (lowerVar, tmpLowerExpression) = createTemporaryVariableIfNecessary(lower, "containsLower")
|
||||
additionalStatements.add(lowerVar!!)
|
||||
lowerExpression = tmpLowerExpression.copy()
|
||||
lowerExpression = tmpLowerExpression.shallowCopy()
|
||||
upperExpression = upper
|
||||
useLowerClauseOnLeftSide = false
|
||||
}
|
||||
@@ -311,27 +312,27 @@ private class Transformer(
|
||||
irCall(lowerCompFun).apply {
|
||||
putValueArgument(0, irInt(0))
|
||||
putValueArgument(1, irCall(compareToFun).apply {
|
||||
dispatchReceiver = argExpression.copy()
|
||||
dispatchReceiver = argExpression.shallowCopy()
|
||||
putValueArgument(0, lowerExpression)
|
||||
})
|
||||
}
|
||||
} else {
|
||||
irCall(lowerCompFun).apply {
|
||||
putValueArgument(0, lowerExpression)
|
||||
putValueArgument(1, argExpression.copy())
|
||||
putValueArgument(1, argExpression.shallowCopy())
|
||||
}
|
||||
}
|
||||
val upperClause = if (useCompareTo) {
|
||||
irCall(upperCompFun).apply {
|
||||
putValueArgument(0, irCall(compareToFun).apply {
|
||||
dispatchReceiver = argExpression.copy()
|
||||
dispatchReceiver = argExpression.shallowCopy()
|
||||
putValueArgument(0, upperExpression)
|
||||
})
|
||||
putValueArgument(1, irInt(0))
|
||||
}
|
||||
} else {
|
||||
irCall(upperCompFun).apply {
|
||||
putValueArgument(0, argExpression.copy())
|
||||
putValueArgument(0, argExpression.shallowCopy())
|
||||
putValueArgument(1, upperExpression)
|
||||
}
|
||||
}
|
||||
|
||||
-4
@@ -592,10 +592,6 @@ class FunctionInlining(
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D) =
|
||||
visitor.visitGetValue(this, data)
|
||||
|
||||
override fun copy(): IrGetValue {
|
||||
TODO("not implemented")
|
||||
}
|
||||
|
||||
fun withLocation(startOffset: Int, endOffset: Int) =
|
||||
IrGetValueImpl(startOffset, endOffset, type, symbol, origin)
|
||||
}
|
||||
|
||||
+6
-6
@@ -66,13 +66,13 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
val inductionVariable: IrVariable
|
||||
|
||||
protected val stepVariable: IrVariable?
|
||||
val stepExpression: IrExpressionWithCopy
|
||||
val stepExpression: IrExpression
|
||||
|
||||
protected val lastVariableIfCanCacheLast: IrVariable?
|
||||
protected val lastExpression: IrExpression
|
||||
// If this is not `IrExpressionWithCopy`, then it is `<IrGetValue>.getSize()` built in `IndexedGetIterationHandler`.
|
||||
// It is therefore safe to deep-copy as it does not contain any functions or classes.
|
||||
get() = if (field is IrExpressionWithCopy) field.copy() else field.deepCopyWithSymbols()
|
||||
get() = field.shallowCopyOrNull() ?: field.deepCopyWithSymbols()
|
||||
|
||||
protected val symbols = context.ir.symbols
|
||||
|
||||
@@ -105,7 +105,7 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
if (headerInfo.canCacheLast) {
|
||||
val (variable, expression) = createTemporaryVariableIfNecessary(last, nameHint = "last")
|
||||
lastVariableIfCanCacheLast = variable
|
||||
lastExpression = expression.copy()
|
||||
lastExpression = expression.shallowCopy()
|
||||
} else {
|
||||
lastVariableIfCanCacheLast = null
|
||||
lastExpression = last
|
||||
@@ -146,7 +146,7 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
inductionVariable.symbol, irCallOp(
|
||||
plusFun.symbol, plusFun.returnType,
|
||||
irGet(inductionVariable),
|
||||
stepExpression.copy(), IrStatementOrigin.PLUSEQ
|
||||
stepExpression.shallowCopy(), IrStatementOrigin.PLUSEQ
|
||||
), IrStatementOrigin.PLUSEQ
|
||||
)
|
||||
}
|
||||
@@ -225,14 +225,14 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
context.oror(
|
||||
context.andand(
|
||||
irCall(builtIns.greaterFunByOperandType.getValue(stepClass.symbol)).apply {
|
||||
putValueArgument(0, stepExpression.copy())
|
||||
putValueArgument(0, stepExpression.shallowCopy())
|
||||
putValueArgument(1, zeroStepExpression())
|
||||
},
|
||||
conditionForIncreasing()
|
||||
),
|
||||
context.andand(
|
||||
irCall(builtIns.lessFunByOperandType.getValue(stepClass.symbol)).apply {
|
||||
putValueArgument(0, stepExpression.copy())
|
||||
putValueArgument(0, stepExpression.shallowCopy())
|
||||
putValueArgument(1, zeroStepExpression())
|
||||
},
|
||||
conditionForDecreasing()
|
||||
|
||||
+2
-10
@@ -5,7 +5,6 @@
|
||||
|
||||
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
|
||||
@@ -14,13 +13,12 @@ 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.ir.util.isTrivial
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
@@ -82,9 +80,6 @@ private fun Any?.toLong(): Long? =
|
||||
else -> null
|
||||
}
|
||||
|
||||
internal val IrExpressionWithCopy.constLongValue: Long?
|
||||
get() = if (this is IrConst<*>) value.toLong() else null
|
||||
|
||||
internal val IrExpression.constLongValue: Long?
|
||||
get() = if (this is IrConst<*>) value.toLong() else null
|
||||
|
||||
@@ -97,13 +92,10 @@ internal val IrExpression.constLongValue: Long?
|
||||
internal fun DeclarationIrBuilder.createTemporaryVariableIfNecessary(
|
||||
expression: IrExpression, nameHint: String? = null,
|
||||
irType: IrType? = null, isMutable: Boolean = false
|
||||
): Pair<IrVariable?, IrExpressionWithCopy> =
|
||||
): Pair<IrVariable?, IrExpression> =
|
||||
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)
|
||||
}
|
||||
|
||||
|
||||
+4
-3
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.getClass
|
||||
import org.jetbrains.kotlin.ir.util.getPropertyGetter
|
||||
import org.jetbrains.kotlin.ir.util.shallowCopy
|
||||
|
||||
/** Builds a [HeaderInfo] for progressions not handled by more specialized handlers. */
|
||||
internal class DefaultProgressionHandler(private val context: CommonBackendContext, private val allowUnsignedBounds: Boolean = false) :
|
||||
@@ -35,10 +36,10 @@ internal class DefaultProgressionHandler(private val context: CommonBackendConte
|
||||
val (progressionVar, progressionExpression) = createTemporaryVariableIfNecessary(expression, nameHint = "progression")
|
||||
val progressionClass = expression.type.getClass()!!
|
||||
val first = irCall(progressionClass.symbol.getPropertyGetter("first")!!).apply {
|
||||
dispatchReceiver = progressionExpression.copy()
|
||||
dispatchReceiver = progressionExpression.shallowCopy()
|
||||
}
|
||||
val last = irCall(progressionClass.symbol.getPropertyGetter("last")!!).apply {
|
||||
dispatchReceiver = progressionExpression.copy()
|
||||
dispatchReceiver = progressionExpression.shallowCopy()
|
||||
}
|
||||
|
||||
// *Ranges (e.g., IntRange) have step == 1 and is always increasing.
|
||||
@@ -47,7 +48,7 @@ internal class DefaultProgressionHandler(private val context: CommonBackendConte
|
||||
irInt(1)
|
||||
} else {
|
||||
irCall(progressionClass.symbol.getPropertyGetter("step")!!).apply {
|
||||
dispatchReceiver = progressionExpression.copy()
|
||||
dispatchReceiver = progressionExpression.shallowCopy()
|
||||
}
|
||||
}
|
||||
val direction = if (isRange) ProgressionDirection.INCREASING else ProgressionDirection.UNKNOWN
|
||||
|
||||
+19
-19
@@ -16,12 +16,12 @@ import org.jetbrains.kotlin.ir.builders.*
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.defaultType
|
||||
import org.jetbrains.kotlin.ir.types.isInt
|
||||
import org.jetbrains.kotlin.ir.types.isLong
|
||||
import org.jetbrains.kotlin.ir.util.defaultType
|
||||
import org.jetbrains.kotlin.ir.util.shallowCopy
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
@@ -79,7 +79,7 @@ internal class StepHandler(
|
||||
irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply {
|
||||
val exceptionMessage = irConcat()
|
||||
exceptionMessage.addArgument(irString("Step must be positive, was: "))
|
||||
exceptionMessage.addArgument(stepArgExpression.copy())
|
||||
exceptionMessage.addArgument(stepArgExpression.shallowCopy())
|
||||
exceptionMessage.addArgument(irString("."))
|
||||
putValueArgument(0, exceptionMessage)
|
||||
}
|
||||
@@ -89,7 +89,7 @@ internal class StepHandler(
|
||||
stepArgValueAsLong == null -> {
|
||||
// Step argument is not a constant. In this case, we check if step <= 0.
|
||||
val stepNonPositiveCheck = irCall(stepCompFun).apply {
|
||||
putValueArgument(0, stepArgExpression.copy())
|
||||
putValueArgument(0, stepArgExpression.shallowCopy())
|
||||
putValueArgument(1, data.run { zeroStepExpression() })
|
||||
}
|
||||
irIfThen(
|
||||
@@ -118,7 +118,7 @@ internal class StepHandler(
|
||||
ProgressionDirection.INCREASING -> stepArgExpression
|
||||
ProgressionDirection.DECREASING -> {
|
||||
if (stepArgVar == null) {
|
||||
stepNegation = scope.createTmpVariable(stepArgExpression.copy().negate())
|
||||
stepNegation = scope.createTmpVariable(stepArgExpression.shallowCopy().negate())
|
||||
irGet(stepNegation)
|
||||
} else {
|
||||
// Step is already stored in a variable, just negate it.
|
||||
@@ -133,7 +133,7 @@ internal class StepHandler(
|
||||
val (tmpNestedStepVar, nestedStepExpression) = createTemporaryVariableIfNecessary(nestedStep, "nestedStep")
|
||||
nestedStepVar = tmpNestedStepVar
|
||||
val nestedStepNonPositiveCheck = irCall(stepCompFun).apply {
|
||||
putValueArgument(0, nestedStepExpression.copy())
|
||||
putValueArgument(0, nestedStepExpression.shallowCopy())
|
||||
putValueArgument(1, data.run { zeroStepExpression() })
|
||||
}
|
||||
if (stepArgVar == null) {
|
||||
@@ -142,8 +142,8 @@ internal class StepHandler(
|
||||
irIfThenElse(
|
||||
stepType,
|
||||
nestedStepNonPositiveCheck,
|
||||
stepArgExpression.copy().negate(),
|
||||
stepArgExpression.copy()
|
||||
stepArgExpression.shallowCopy().negate(),
|
||||
stepArgExpression.shallowCopy()
|
||||
),
|
||||
nameHint = "maybeNegatedStep"
|
||||
)
|
||||
@@ -272,9 +272,9 @@ internal class StepHandler(
|
||||
|
||||
return ProgressionHeaderInfo(
|
||||
data,
|
||||
first = nestedFirstExpression.copy(),
|
||||
first = nestedFirstExpression.shallowCopy(),
|
||||
last = recalculatedLast,
|
||||
step = finalStepExpression.copy(),
|
||||
step = finalStepExpression.shallowCopy(),
|
||||
isReversed = nestedInfo.isReversed,
|
||||
additionalStatements = additionalStatements,
|
||||
direction = nestedInfo.direction
|
||||
@@ -283,13 +283,13 @@ internal class StepHandler(
|
||||
|
||||
private fun DeclarationIrBuilder.callGetProgressionLastElementIfNecessary(
|
||||
progressionType: ProgressionType,
|
||||
first: IrExpressionWithCopy,
|
||||
last: IrExpressionWithCopy,
|
||||
step: IrExpressionWithCopy
|
||||
first: IrExpression,
|
||||
last: IrExpression,
|
||||
step: IrExpression
|
||||
): IrExpression {
|
||||
// Calling getProgressionLastElement() is not needed if step == 1 or -1; the "last" value is unchanged in such cases.
|
||||
if (step.constLongValue?.absoluteValue == 1L) {
|
||||
return last.copy()
|
||||
return last.shallowCopy()
|
||||
}
|
||||
|
||||
// Call `getProgressionLastElement(first, last, step)`. The following overloads are present in the stdlib:
|
||||
@@ -304,17 +304,17 @@ internal class StepHandler(
|
||||
// Bounds are signed for unsigned progressions but `getProgressionLastElement` expects unsigned.
|
||||
// The return value is finally converted back to signed since it will be assigned back to `last`.
|
||||
irCall(getProgressionLastElementFun).apply {
|
||||
putValueArgument(0, first.copy().asElementType().asUnsigned())
|
||||
putValueArgument(1, last.copy().asElementType().asUnsigned())
|
||||
putValueArgument(2, step.copy().asStepType())
|
||||
putValueArgument(0, first.shallowCopy().asElementType().asUnsigned())
|
||||
putValueArgument(1, last.shallowCopy().asElementType().asUnsigned())
|
||||
putValueArgument(2, step.shallowCopy().asStepType())
|
||||
}.asSigned()
|
||||
} else {
|
||||
irCall(getProgressionLastElementFun).apply {
|
||||
// Step type is used for casting because it works for all signed progressions. In particular,
|
||||
// getProgressionLastElement(Int, Int, Int) is called for CharProgression, which uses an Int step.
|
||||
putValueArgument(0, first.copy().asStepType())
|
||||
putValueArgument(1, last.copy().asStepType())
|
||||
putValueArgument(2, step.copy().asStepType())
|
||||
putValueArgument(0, first.shallowCopy().asStepType())
|
||||
putValueArgument(1, last.shallowCopy().asStepType())
|
||||
putValueArgument(2, step.shallowCopy().asStepType())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+6
-8
@@ -6,15 +6,15 @@
|
||||
package org.jetbrains.kotlin.ir.backend.js.lower
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.ir.isPure
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrArithBuilder
|
||||
import org.jetbrains.kotlin.ir.backend.js.ir.JsIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.ir.isPure
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase
|
||||
import org.jetbrains.kotlin.ir.declarations.IrDeclarationParent
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
||||
@@ -47,6 +47,7 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : BodyLoweringPass {
|
||||
private val isInterfaceSymbol get() = context.intrinsics.isInterfaceSymbol
|
||||
private val isArraySymbol get() = context.intrinsics.isArraySymbol
|
||||
private val isSuspendFunctionSymbol = context.intrinsics.isSuspendFunctionSymbol
|
||||
|
||||
// private val isCharSymbol get() = context.intrinsics.isCharSymbol
|
||||
private val isObjectSymbol get() = context.intrinsics.isObjectSymbol
|
||||
|
||||
@@ -269,11 +270,8 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : BodyLoweringPass {
|
||||
// assert(!typeParameter.isReified) { "reified parameters have to be lowered before" }
|
||||
|
||||
return typeParameter.superTypes.fold<IrType, IrExpression?>(null) { r, t ->
|
||||
val copy = if (argument is IrExpressionWithCopy) {
|
||||
argument.copy()
|
||||
} else {
|
||||
argument.deepCopyWithSymbols()
|
||||
}
|
||||
val copy = argument.shallowCopyOrNull()
|
||||
?: argument.deepCopyWithSymbols()
|
||||
val check = generateTypeCheckNonNull(copy, t.makeNotNull())
|
||||
|
||||
if (r == null) {
|
||||
@@ -361,7 +359,7 @@ class TypeOperatorLowering(val context: JsIrBackendContext) : BodyLoweringPass {
|
||||
val toType = expression.typeOperand
|
||||
|
||||
fun maskOp(arg: IrExpression, mask: IrExpression, shift: IrConst<*>) = calculator.run {
|
||||
shr(shl(and(arg, mask), shift), shift.copy())
|
||||
shr(shl(and(arg, mask), shift), shift.shallowCopy())
|
||||
}
|
||||
|
||||
val newStatements = mutableListOf<IrStatement>()
|
||||
|
||||
+1
-1
@@ -122,7 +122,7 @@ private class MoveOrCopyCompanionObjectFieldsLowering(val context: JvmBackendCon
|
||||
correspondingPropertySymbol = property.symbol
|
||||
annotations += oldField.annotations
|
||||
initializer = with(oldField.initializer!!) {
|
||||
IrExpressionBodyImpl(startOffset, endOffset, (expression as IrConst<*>).copy())
|
||||
IrExpressionBodyImpl(startOffset, endOffset, (expression as IrConst<*>).shallowCopy())
|
||||
}
|
||||
|
||||
if (oldProperty.parentAsClass.visibility == DescriptorVisibilities.PRIVATE) {
|
||||
|
||||
+15
-15
@@ -69,8 +69,8 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
|
||||
}
|
||||
}
|
||||
|
||||
private fun IrBlockBuilder.cacheValue(value: IrExpression): () -> IrExpressionWithCopy {
|
||||
if (value.isPure(true) && value is IrExpressionWithCopy) {
|
||||
private fun IrBlockBuilder.cacheValue(value: IrExpression): () -> IrExpression {
|
||||
if (value.isPure(true) && value.isTrivial()) {
|
||||
return { value.deepCopyWithSymbols() }
|
||||
}
|
||||
val tmpVal = createTmpVariable(value)
|
||||
@@ -84,12 +84,12 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
|
||||
get() = this.erasedUpperBound?.defaultType ?: builtIns.anyType
|
||||
|
||||
private fun generateTypeCheck(
|
||||
valueProvider: () -> IrExpressionWithCopy,
|
||||
valueProvider: () -> IrExpression,
|
||||
toType: IrType
|
||||
): IrExpression {
|
||||
val toNotNullable = toType.makeNotNull()
|
||||
val valueInstance: IrExpressionWithCopy = valueProvider()
|
||||
val fromType = (valueInstance as IrExpression).type
|
||||
val valueInstance: IrExpression = valueProvider()
|
||||
val fromType = valueInstance.type
|
||||
|
||||
// Inlined values have no type information on runtime.
|
||||
// But since they are final we can compute type checks on compile time.
|
||||
@@ -108,7 +108,7 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
|
||||
else ->
|
||||
builder.irIfThenElse(
|
||||
type = builtIns.booleanType,
|
||||
condition = builder.irEqualsNull(valueProvider() as IrExpression),
|
||||
condition = builder.irEqualsNull(valueProvider()),
|
||||
thenPart = builder.irBoolean(isToNullable),
|
||||
elsePart = instanceCheck
|
||||
)
|
||||
@@ -129,16 +129,16 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
|
||||
else -> error("Unreachable execution (coercion to non-Integer type")
|
||||
}
|
||||
|
||||
private fun generateTypeCheckNonNull(argument: IrExpressionWithCopy, toType: IrType): IrExpression {
|
||||
private fun generateTypeCheckNonNull(argument: IrExpression, toType: IrType): IrExpression {
|
||||
assert(!toType.isMarkedNullable())
|
||||
return when {
|
||||
toType.isNothing() -> builder.irComposite(resultType = builtIns.booleanType) {
|
||||
+(argument as IrExpression)
|
||||
+(argument)
|
||||
+builder.irFalse()
|
||||
}
|
||||
toType.isTypeParameter() -> generateTypeCheckWithTypeParameter(argument, toType)
|
||||
toType.isInterface() -> generateIsInterface(argument as IrExpression, toType)
|
||||
else -> generateIsSubClass(argument as IrExpression, toType)
|
||||
toType.isInterface() -> generateIsInterface(argument, toType)
|
||||
else -> generateIsSubClass(argument, toType)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -188,12 +188,12 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
|
||||
val cachedValue = cacheValue(value)
|
||||
+builder.irIfNull(
|
||||
type = toType,
|
||||
subject = cachedValue() as IrExpression,
|
||||
subject = cachedValue(),
|
||||
thenPart = builder.irNull(toType),
|
||||
elsePart = builder.irCall(symbols.wasmRefCast, type = toType).apply {
|
||||
putTypeArgument(0, fromType)
|
||||
putTypeArgument(1, toType)
|
||||
putValueArgument(0, cachedValue() as IrExpression)
|
||||
putValueArgument(0, cachedValue())
|
||||
}
|
||||
)
|
||||
}
|
||||
@@ -225,7 +225,7 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
|
||||
|
||||
return builder.irComposite(resultType = expression.type) {
|
||||
val argument = cacheValue(expression.argument)
|
||||
val narrowArg = narrowType(fromType, expression.type, argument() as IrExpression)
|
||||
val narrowArg = narrowType(fromType, expression.type, argument())
|
||||
val check = generateTypeCheck(argument, toType)
|
||||
if (check is IrConst<*>) {
|
||||
val value = check.value as Boolean
|
||||
@@ -252,12 +252,12 @@ class WasmBaseTypeOperatorTransformer(val context: WasmBackendContext) : IrEleme
|
||||
value = expression.argument
|
||||
)
|
||||
|
||||
private fun generateTypeCheckWithTypeParameter(argument: IrExpressionWithCopy, toType: IrType): IrExpression {
|
||||
private fun generateTypeCheckWithTypeParameter(argument: IrExpression, toType: IrType): IrExpression {
|
||||
val typeParameter = toType.classifierOrNull?.owner as? IrTypeParameter
|
||||
?: error("expected type parameter, but got $toType")
|
||||
|
||||
return typeParameter.superTypes.fold(builder.irTrue() as IrExpression) { r, t ->
|
||||
val check = generateTypeCheckNonNull(argument.copy() as IrExpressionWithCopy, t.makeNotNull())
|
||||
val check = generateTypeCheckNonNull(argument.shallowCopy(), t.makeNotNull())
|
||||
builder.irCall(symbols.booleanAnd).apply {
|
||||
putValueArgument(0, r)
|
||||
putValueArgument(1, check)
|
||||
|
||||
+2
-1
@@ -33,6 +33,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.isTrivial
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.psi.KtElement
|
||||
import org.jetbrains.kotlin.psi.KtExpression
|
||||
@@ -109,7 +110,7 @@ fun StatementGenerator.generateReceiver(defaultStartOffset: Int, defaultEndOffse
|
||||
TODO("Receiver: ${receiver::class.java.simpleName}")
|
||||
}
|
||||
|
||||
if (receiverExpression is IrExpressionWithCopy)
|
||||
if (receiverExpression.isTrivial())
|
||||
RematerializableValue(receiverExpression.type, receiverExpression)
|
||||
else
|
||||
OnceExpressionValue(receiverExpression)
|
||||
|
||||
+3
-3
@@ -19,12 +19,12 @@ package org.jetbrains.kotlin.psi2ir.intermediate
|
||||
import org.jetbrains.kotlin.ir.builders.IrGeneratorContext
|
||||
import org.jetbrains.kotlin.ir.builders.Scope
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementContainer
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.util.shallowCopy
|
||||
|
||||
class RematerializableValue(override val type: IrType, val irExpression: IrExpressionWithCopy) : IntermediateValue {
|
||||
override fun load(): IrExpression = irExpression.copy()
|
||||
class RematerializableValue(override val type: IrType, val irExpression: IrExpression) : IntermediateValue {
|
||||
override fun load(): IrExpression = irExpression.shallowCopy()
|
||||
}
|
||||
|
||||
fun Scope.createTemporaryVariableInBlock(
|
||||
|
||||
@@ -16,11 +16,10 @@
|
||||
|
||||
package org.jetbrains.kotlin.ir.expressions
|
||||
|
||||
abstract class IrConst<T> : IrExpression(), IrExpressionWithCopy {
|
||||
abstract class IrConst<T> : IrExpression() {
|
||||
abstract val kind: IrConstKind<T>
|
||||
abstract val value: T
|
||||
|
||||
abstract override fun copy(): IrConst<T>
|
||||
abstract fun copyWithOffsets(startOffset: Int, endOffset: Int): IrConst<T>
|
||||
}
|
||||
|
||||
|
||||
+1
-1
@@ -27,7 +27,7 @@ abstract class IrDeclarationReference : IrExpression() {
|
||||
|
||||
abstract class IrGetSingletonValue : IrDeclarationReference()
|
||||
|
||||
abstract class IrGetObjectValue : IrGetSingletonValue(), IrExpressionWithCopy {
|
||||
abstract class IrGetObjectValue : IrGetSingletonValue() {
|
||||
abstract override val symbol: IrClassSymbol
|
||||
}
|
||||
|
||||
|
||||
@@ -39,8 +39,4 @@ abstract class IrExpression : IrElementBase(), IrStatement, IrVarargElement, IrA
|
||||
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
|
||||
// No children by default
|
||||
}
|
||||
}
|
||||
|
||||
interface IrExpressionWithCopy {
|
||||
fun copy(): IrExpression
|
||||
}
|
||||
}
|
||||
+1
-3
@@ -25,9 +25,7 @@ abstract class IrValueAccessExpression : IrDeclarationReference() {
|
||||
abstract val origin: IrStatementOrigin?
|
||||
}
|
||||
|
||||
abstract class IrGetValue : IrValueAccessExpression(), IrExpressionWithCopy {
|
||||
abstract override fun copy(): IrGetValue
|
||||
}
|
||||
abstract class IrGetValue : IrValueAccessExpression()
|
||||
|
||||
abstract class IrSetValue : IrValueAccessExpression() {
|
||||
abstract override val symbol: IrValueSymbol
|
||||
|
||||
@@ -32,9 +32,6 @@ class IrConstImpl<T>(
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitConst(this, data)
|
||||
|
||||
override fun copy(): IrConst<T> =
|
||||
IrConstImpl(startOffset, endOffset, type, kind, value)
|
||||
|
||||
override fun copyWithOffsets(startOffset: Int, endOffset: Int) =
|
||||
IrConstImpl(startOffset, endOffset, type, kind, value)
|
||||
|
||||
|
||||
+1
-5
@@ -17,7 +17,6 @@
|
||||
package org.jetbrains.kotlin.ir.expressions.impl
|
||||
|
||||
import org.jetbrains.kotlin.ir.expressions.IrErrorExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpressionWithCopy
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
|
||||
@@ -26,10 +25,7 @@ class IrErrorExpressionImpl(
|
||||
override val endOffset: Int,
|
||||
override var type: IrType,
|
||||
override val description: String
|
||||
) : IrErrorExpression(), IrExpressionWithCopy {
|
||||
) : IrErrorExpression() {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitErrorExpression(this, data)
|
||||
|
||||
override fun copy(): IrErrorExpressionImpl =
|
||||
IrErrorExpressionImpl(startOffset, endOffset, type, description)
|
||||
}
|
||||
|
||||
-4
@@ -30,8 +30,4 @@ class IrGetObjectValueImpl(
|
||||
) : IrGetObjectValue() {
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitGetObjectValue(this, data)
|
||||
|
||||
override fun copy(): IrExpression {
|
||||
return IrGetObjectValueImpl(startOffset, endOffset, type, symbol)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,7 +27,4 @@ class IrGetValueImpl(
|
||||
|
||||
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R =
|
||||
visitor.visitGetValue(this, data)
|
||||
|
||||
override fun copy(): IrGetValue =
|
||||
IrGetValueImpl(startOffset, endOffset, type, symbol, origin)
|
||||
}
|
||||
|
||||
@@ -392,7 +392,7 @@ open class DeepCopyIrTreeWithSymbols(
|
||||
throw IllegalArgumentException("Unsupported expression type: $expression")
|
||||
|
||||
override fun <T> visitConst(expression: IrConst<T>): IrConst<T> =
|
||||
expression.copy().copyAttributes(expression)
|
||||
expression.shallowCopy().copyAttributes(expression)
|
||||
|
||||
override fun visitVararg(expression: IrVararg): IrVararg =
|
||||
IrVarargImpl(
|
||||
|
||||
@@ -12,9 +12,7 @@ import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
|
||||
import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrTypeOperatorCallImpl
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||
import org.jetbrains.kotlin.ir.symbols.*
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
@@ -558,4 +556,50 @@ val IrFunction.originalFunction: IrFunction
|
||||
get() = (this as? IrAttributeContainer)?.attributeOwnerId as? IrFunction ?: this
|
||||
|
||||
val IrProperty.originalProperty: IrProperty
|
||||
get() = attributeOwnerId as? IrProperty ?: this
|
||||
get() = attributeOwnerId as? IrProperty ?: this
|
||||
|
||||
fun IrExpression.isTrivial() =
|
||||
this is IrConst<*> ||
|
||||
this is IrGetValue ||
|
||||
this is IrGetObjectValue ||
|
||||
this is IrErrorExpressionImpl
|
||||
|
||||
fun IrExpression.shallowCopy(): IrExpression =
|
||||
shallowCopyOrNull()
|
||||
?: error("Not a copyable expression: ${render()}")
|
||||
|
||||
fun IrExpression.shallowCopyOrNull(): IrExpression? =
|
||||
when (this) {
|
||||
is IrConst<*> -> shallowCopy()
|
||||
is IrGetObjectValue ->
|
||||
IrGetObjectValueImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
type,
|
||||
symbol
|
||||
)
|
||||
is IrGetValueImpl ->
|
||||
IrGetValueImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
type,
|
||||
symbol,
|
||||
origin
|
||||
)
|
||||
is IrErrorExpressionImpl ->
|
||||
IrErrorExpressionImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
type,
|
||||
description
|
||||
)
|
||||
else -> null
|
||||
}
|
||||
|
||||
internal fun <T> IrConst<T>.shallowCopy() = IrConstImpl(
|
||||
startOffset,
|
||||
endOffset,
|
||||
type,
|
||||
kind,
|
||||
value
|
||||
)
|
||||
Reference in New Issue
Block a user