when: emit lookupswitch/tableswitch if possible
A lookupswitch or tableswitch can be used if all conditions are equality
checks to constants. To be more specific, it can be done if:
1. All conditions are CALL 'EQEQ(Any?, Any?)': Boolean
2. All types of variables involved in comparison are in the same group
of Char/Byte/Short/Int, String or enum.
3. All arg0 refer to the same value.
4. All arg1 are IrConst<*>.
Change-Id: Ifd7cb618395f6c5cc64601018b446f0bb7f5891c
This commit is contained in:
committed by
max-kammerer
parent
f5d0a38629
commit
c1d721a15f
@@ -186,12 +186,7 @@ abstract class SwitchCodegen(
|
||||
val minValue = keys.first()
|
||||
val rangeLength = maxValue.toLong() - minValue.toLong() + 1L
|
||||
|
||||
// In modern JVM implementations it shouldn't matter very much for runtime performance
|
||||
// whether to choose lookupswitch or tableswitch.
|
||||
// The only metric that really matters is bytecode size and here we can estimate:
|
||||
// - lookupswitch: ~ 2 * labelsNumber
|
||||
// - tableswitch: ~ rangeLength
|
||||
if (rangeLength > 2L * labelsNumber || rangeLength > Int.MAX_VALUE) {
|
||||
if (preferLookupOverSwitch(labelsNumber, rangeLength)) {
|
||||
val labels = transitionsTable.values.toTypedArray()
|
||||
v.lookupswitch(defaultLabel, keys, labels)
|
||||
return
|
||||
@@ -219,4 +214,13 @@ abstract class SwitchCodegen(
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
// In modern JVM implementations it shouldn't matter very much for runtime performance
|
||||
// whether to choose lookupswitch or tableswitch.
|
||||
// The only metric that really matters is bytecode size and here we can estimate:
|
||||
// - lookupswitch: ~ 2 * labelsNumber
|
||||
// - tableswitch: ~ rangeLength
|
||||
fun preferLookupOverSwitch(labelsNumber: Int, rangeLength: Long) = rangeLength > 2L * labelsNumber || rangeLength > Int.MAX_VALUE
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user