[IR BE] Remove usage of KotlinType from ir loop optimization

This commit is contained in:
Roman Artemev
2020-04-20 13:58:39 +03:00
committed by romanart
parent c38ba45c1b
commit da661e4db7
4 changed files with 23 additions and 12 deletions
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.IrPackageFragment import org.jetbrains.kotlin.ir.declarations.IrPackageFragment
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
@@ -95,11 +96,14 @@ open class BuiltinSymbolsBase(protected val builtIns: KotlinBuiltIns, private va
val progressionClasses = listOf(charProgression, intProgression, longProgression) val progressionClasses = listOf(charProgression, intProgression, longProgression)
val progressionClassesTypes = progressionClasses.map { it.descriptor.defaultType }.toSet() val progressionClassesTypes = progressionClasses.map { it.descriptor.defaultType }.toSet()
val getProgressionLastElementByReturnType = builtInsPackage("kotlin", "internal").getContributedFunctions( val getProgressionLastElementByReturnType = builtInsPackage("kotlin", "internal")
Name.identifier("getProgressionLastElement"), .getContributedFunctions(Name.identifier("getProgressionLastElement"), NoLookupLocation.FROM_BACKEND)
NoLookupLocation.FROM_BACKEND .filter { it.containingDeclaration !is BuiltInsPackageFragment }
).filter { it.containingDeclaration !is BuiltInsPackageFragment } .map { d ->
.map { Pair(it.returnType!!, symbolTable.referenceSimpleFunction(it)) }.toMap() val c = d.returnType?.constructor?.declarationDescriptor?.let { symbolTable.referenceClassifier(it) }
val f = symbolTable.referenceSimpleFunction(d)
c to f
}.toMap()
val any = symbolTable.referenceClass(builtIns.any) val any = symbolTable.referenceClass(builtIns.any)
val unit = symbolTable.referenceClass(builtIns.unit) val unit = symbolTable.referenceClass(builtIns.unit)
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns import org.jetbrains.kotlin.ir.descriptors.IrBuiltIns
import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.isSubtypeOfClass import org.jetbrains.kotlin.ir.types.isSubtypeOfClass
@@ -42,6 +43,12 @@ internal enum class ProgressionType(val elementCastFunctionName: Name, val stepC
LONG_PROGRESSION -> builtIns.longType LONG_PROGRESSION -> builtIns.longType
} }
/** Returns the [IrClassSymbol] of the `step` property type constructor in the progression. */
fun stepClassifier(builtIns: IrBuiltIns): IrClassSymbol = when(this) {
INT_PROGRESSION, CHAR_PROGRESSION -> builtIns.intClass
LONG_PROGRESSION -> builtIns.longClass
}
companion object { companion object {
fun fromIrType(irType: IrType, symbols: Symbols<CommonBackendContext>): ProgressionType? = when { fun fromIrType(irType: IrType, symbols: Symbols<CommonBackendContext>): ProgressionType? = when {
irType.isSubtypeOfClass(symbols.charProgression) -> CHAR_PROGRESSION irType.isSubtypeOfClass(symbols.charProgression) -> CHAR_PROGRESSION
@@ -183,11 +183,11 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
// If the direction is unknown, we check depending on the "step" value: // If the direction is unknown, we check depending on the "step" value:
// // (use `<` if last is exclusive) // // (use `<` if last is exclusive)
// (step > 0 && inductionVar <= last) || (step < 0 || last <= inductionVar) // (step > 0 && inductionVar <= last) || (step < 0 || last <= inductionVar)
val stepType = progressionType.stepType(builtIns) val stepTypeClassifier = progressionType.stepClassifier(builtIns)
val isLong = progressionType == ProgressionType.LONG_PROGRESSION val isLong = progressionType == ProgressionType.LONG_PROGRESSION
context.oror( context.oror(
context.andand( context.andand(
irCall(builtIns.greaterFunByOperandType[stepType.classifierOrFail]!!).apply { irCall(builtIns.greaterFunByOperandType[stepTypeClassifier]!!).apply {
putValueArgument(0, irGet(stepVariable)) putValueArgument(0, irGet(stepVariable))
putValueArgument(1, if (isLong) irLong(0) else irInt(0)) putValueArgument(1, if (isLong) irLong(0) else irInt(0))
}, },
@@ -196,7 +196,7 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
putValueArgument(1, lastExpression) putValueArgument(1, lastExpression)
}), }),
context.andand( context.andand(
irCall(builtIns.lessFunByOperandType[stepType.classifierOrFail]!!).apply { irCall(builtIns.lessFunByOperandType[stepTypeClassifier]!!).apply {
putValueArgument(0, irGet(stepVariable)) putValueArgument(0, irGet(stepVariable))
putValueArgument(1, if (isLong) irLong(0) else irInt(0)) putValueArgument(1, if (isLong) irLong(0) else irInt(0))
}, },
@@ -257,7 +257,7 @@ internal class StepHandler(
// //
// We insert this check in the lowered form only if necessary. // We insert this check in the lowered form only if necessary.
val stepType = data.stepType(context.irBuiltIns) val stepType = data.stepType(context.irBuiltIns)
val stepGreaterFun = context.irBuiltIns.greaterFunByOperandType[stepType.classifierOrFail]!! val stepGreaterFun = context.irBuiltIns.greaterFunByOperandType[data.stepClassifier(context.irBuiltIns)]!!
val zeroStep = if (data == ProgressionType.LONG_PROGRESSION) irLong(0) else irInt(0) val zeroStep = if (data == ProgressionType.LONG_PROGRESSION) irLong(0) else irInt(0)
val throwIllegalStepExceptionCall = { val throwIllegalStepExceptionCall = {
irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply { irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply {
@@ -459,9 +459,9 @@ internal class StepHandler(
} }
// Call `getProgressionLastElement(first, last, step)` // Call `getProgressionLastElement(first, last, step)`
val stepType = progressionType.stepType(context.irBuiltIns).toKotlinType() val stepTypeClassifier = progressionType.stepClassifier(context.irBuiltIns)
val getProgressionLastElementFun = symbols.getProgressionLastElementByReturnType[stepType] val getProgressionLastElementFun = symbols.getProgressionLastElementByReturnType[stepTypeClassifier]
?: throw IllegalArgumentException("No `getProgressionLastElement` for step type $stepType") ?: throw IllegalArgumentException("No `getProgressionLastElement` for step type $stepTypeClassifier")
return irCall(getProgressionLastElementFun).apply { return irCall(getProgressionLastElementFun).apply {
putValueArgument( putValueArgument(
0, first.deepCopyWithSymbols().castIfNecessary( 0, first.deepCopyWithSymbols().castIfNecessary(