[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.IrModuleFragment
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.IrFunctionSymbol
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 progressionClassesTypes = progressionClasses.map { it.descriptor.defaultType }.toSet()
val getProgressionLastElementByReturnType = builtInsPackage("kotlin", "internal").getContributedFunctions(
Name.identifier("getProgressionLastElement"),
NoLookupLocation.FROM_BACKEND
).filter { it.containingDeclaration !is BuiltInsPackageFragment }
.map { Pair(it.returnType!!, symbolTable.referenceSimpleFunction(it)) }.toMap()
val getProgressionLastElementByReturnType = builtInsPackage("kotlin", "internal")
.getContributedFunctions(Name.identifier("getProgressionLastElement"), NoLookupLocation.FROM_BACKEND)
.filter { it.containingDeclaration !is BuiltInsPackageFragment }
.map { d ->
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 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.expressions.IrCall
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.types.IrType
import org.jetbrains.kotlin.ir.types.isSubtypeOfClass
@@ -42,6 +43,12 @@ internal enum class ProgressionType(val elementCastFunctionName: Name, val stepC
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 {
fun fromIrType(irType: IrType, symbols: Symbols<CommonBackendContext>): ProgressionType? = when {
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:
// // (use `<` if last is exclusive)
// (step > 0 && inductionVar <= last) || (step < 0 || last <= inductionVar)
val stepType = progressionType.stepType(builtIns)
val stepTypeClassifier = progressionType.stepClassifier(builtIns)
val isLong = progressionType == ProgressionType.LONG_PROGRESSION
context.oror(
context.andand(
irCall(builtIns.greaterFunByOperandType[stepType.classifierOrFail]!!).apply {
irCall(builtIns.greaterFunByOperandType[stepTypeClassifier]!!).apply {
putValueArgument(0, irGet(stepVariable))
putValueArgument(1, if (isLong) irLong(0) else irInt(0))
},
@@ -196,7 +196,7 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
putValueArgument(1, lastExpression)
}),
context.andand(
irCall(builtIns.lessFunByOperandType[stepType.classifierOrFail]!!).apply {
irCall(builtIns.lessFunByOperandType[stepTypeClassifier]!!).apply {
putValueArgument(0, irGet(stepVariable))
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.
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 throwIllegalStepExceptionCall = {
irCall(context.irBuiltIns.illegalArgumentExceptionSymbol).apply {
@@ -459,9 +459,9 @@ internal class StepHandler(
}
// Call `getProgressionLastElement(first, last, step)`
val stepType = progressionType.stepType(context.irBuiltIns).toKotlinType()
val getProgressionLastElementFun = symbols.getProgressionLastElementByReturnType[stepType]
?: throw IllegalArgumentException("No `getProgressionLastElement` for step type $stepType")
val stepTypeClassifier = progressionType.stepClassifier(context.irBuiltIns)
val getProgressionLastElementFun = symbols.getProgressionLastElementByReturnType[stepTypeClassifier]
?: throw IllegalArgumentException("No `getProgressionLastElement` for step type $stepTypeClassifier")
return irCall(getProgressionLastElementFun).apply {
putValueArgument(
0, first.deepCopyWithSymbols().castIfNecessary(