[WASM] When expressions optimisations for String and Int constant cases
This commit is contained in:
+2
-68
@@ -5,12 +5,11 @@
|
||||
|
||||
package org.jetbrains.kotlin.backend.jvm.codegen
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.IrWhenUtils
|
||||
import org.jetbrains.kotlin.codegen.`when`.SwitchCodegen.Companion.preferLookupOverSwitch
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.util.hasAnnotation
|
||||
import org.jetbrains.kotlin.ir.util.isTrueConst
|
||||
import org.jetbrains.kotlin.load.java.JvmAnnotationNames
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
@@ -32,7 +31,7 @@ class SwitchGenerator(private val expression: IrWhen, private val data: BlockInf
|
||||
if (branch is IrElseBranch) {
|
||||
elseExpression = branch.result
|
||||
} else {
|
||||
val conditions = matchConditions(branch.condition) ?: return null
|
||||
val conditions = IrWhenUtils.matchConditions(codegen.context.irBuiltIns.ororSymbol, branch.condition) ?: return null
|
||||
val thenLabel = Label()
|
||||
expressionToLabels.add(ExpressionToLabel(branch.result, thenLabel))
|
||||
callToLabels += conditions.map { CallToLabel(it, thenLabel) }
|
||||
@@ -234,71 +233,6 @@ class SwitchGenerator(private val expression: IrWhen, private val data: BlockInf
|
||||
removeIf { it.label !in reachableLabels }
|
||||
}
|
||||
|
||||
// psi2ir lowers multiple cases to nested conditions. For example,
|
||||
//
|
||||
// when (subject) {
|
||||
// a, b, c -> action
|
||||
// }
|
||||
//
|
||||
// is lowered to
|
||||
//
|
||||
// if (if (subject == a)
|
||||
// true
|
||||
// else
|
||||
// if (subject == b)
|
||||
// true
|
||||
// else
|
||||
// subject == c) {
|
||||
// action
|
||||
// }
|
||||
//
|
||||
// fir2ir lowers the same to an or sequence:
|
||||
//
|
||||
// if (((subject == a) || (subject == b)) || (subject = c)) action
|
||||
//
|
||||
// @return true if the conditions are equality checks of constants.
|
||||
private fun matchConditions(condition: IrExpression): ArrayList<IrCall>? {
|
||||
if (condition is IrWhen && condition.origin == IrStatementOrigin.WHEN_COMMA) {
|
||||
assert(condition.type.isBoolean()) { "WHEN_COMMA should always be a Boolean: ${condition.dump()}" }
|
||||
|
||||
val candidates = ArrayList<IrCall>()
|
||||
|
||||
// Match the following structure:
|
||||
//
|
||||
// when() {
|
||||
// cond_1 -> true
|
||||
// cond_2 -> true
|
||||
// ...
|
||||
// else -> cond_N
|
||||
// }
|
||||
//
|
||||
// Namely, the structure which returns true if any one of the condition is true.
|
||||
for (branch in condition.branches) {
|
||||
candidates += if (branch is IrElseBranch) {
|
||||
assert(branch.condition.isTrueConst()) { "IrElseBranch.condition should be const true: ${branch.condition.dump()}" }
|
||||
matchConditions(branch.result) ?: return null
|
||||
} else {
|
||||
if (!branch.result.isTrueConst())
|
||||
return null
|
||||
matchConditions(branch.condition) ?: return null
|
||||
}
|
||||
}
|
||||
|
||||
return if (candidates.isNotEmpty()) candidates else return null
|
||||
} else if (condition is IrCall && condition.symbol == codegen.context.irBuiltIns.ororSymbol) {
|
||||
val candidates = ArrayList<IrCall>()
|
||||
for (i in 0 until condition.valueArgumentsCount) {
|
||||
val argument = condition.getValueArgument(i)!!
|
||||
candidates += matchConditions(argument) ?: return null
|
||||
}
|
||||
return if (candidates.isNotEmpty()) candidates else return null
|
||||
} else if (condition is IrCall) {
|
||||
return arrayListOf(condition)
|
||||
}
|
||||
|
||||
return null
|
||||
}
|
||||
|
||||
abstract inner class Switch(
|
||||
val subject: IrExpression,
|
||||
val elseExpression: IrExpression?,
|
||||
|
||||
Reference in New Issue
Block a user