JVM_IR: Do not materialize negated boolean for branches.
Instead, flip the branch targets. This generates java byte code
such as:
L2
IFNE L3
ALOAD 0
INVOKEVIRTUAL A.getX ()F
GOTO L4
L3
instead of:
L2
IFNE L3
ICONST_1
GOTO L4
L3
ICONST_0
L4
IFEQ L5
ALOAD 0
INVOKEVIRTUAL A.getX ()F
GOTO L6
L5
This commit is contained in:
committed by
Mikhael Bogdanov
parent
02d9c526e2
commit
864b90f8c0
+17
-3
@@ -19,6 +19,7 @@ import org.jetbrains.kotlin.codegen.inline.ReifiedTypeInliner
|
|||||||
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages
|
import org.jetbrains.kotlin.codegen.inline.ReifiedTypeParametersUsages
|
||||||
import org.jetbrains.kotlin.codegen.inline.TypeParameterMappings
|
import org.jetbrains.kotlin.codegen.inline.TypeParameterMappings
|
||||||
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty
|
import org.jetbrains.kotlin.codegen.intrinsics.JavaClassProperty
|
||||||
|
import org.jetbrains.kotlin.codegen.intrinsics.Not
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
||||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fixStackAndJump
|
import org.jetbrains.kotlin.codegen.pseudoInsns.fixStackAndJump
|
||||||
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
import org.jetbrains.kotlin.codegen.signature.BothSignatureWriter
|
||||||
@@ -638,13 +639,26 @@ class ExpressionCodegen(
|
|||||||
|
|
||||||
private fun genIfWithBranches(branch: IrBranch, data: BlockInfo, type: KotlinType, otherBranches: List<IrBranch>): StackValue {
|
private fun genIfWithBranches(branch: IrBranch, data: BlockInfo, type: KotlinType, otherBranches: List<IrBranch>): StackValue {
|
||||||
val elseLabel = Label()
|
val elseLabel = Label()
|
||||||
val condition = branch.condition
|
var condition = branch.condition
|
||||||
val thenBranch = branch.result
|
val thenBranch = branch.result
|
||||||
//TODO don't generate condition for else branch - java verifier fails with empty stack
|
//TODO don't generate condition for else branch - java verifier fails with empty stack
|
||||||
val elseBranch = branch is IrElseBranch
|
val elseBranch = branch is IrElseBranch
|
||||||
if (!elseBranch) {
|
if (!elseBranch) {
|
||||||
gen(condition, data)
|
var jumpIfFalse = true
|
||||||
BranchedValue.condJump(StackValue.onStack(condition.asmType), elseLabel, true, mv)
|
// TODO: there should be only one representation of the 'not' operator.
|
||||||
|
if (condition is IrCall && (
|
||||||
|
condition.symbol == classCodegen.context.irBuiltIns.booleanNotSymbol ||
|
||||||
|
classCodegen.state.intrinsics.getIntrinsic(condition.symbol.descriptor) is Not
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
// Instead of materializing a negated value when used for control flow, flip the branch
|
||||||
|
// targets instead. This significantly cuts down the amount of branches and loads of
|
||||||
|
// const_0 and const_1 in the generated java bytecode.
|
||||||
|
condition = condition.dispatchReceiver ?: condition.getValueArgument(0)!!
|
||||||
|
jumpIfFalse = false
|
||||||
|
}
|
||||||
|
gen(condition, data).put(condition.asmType, mv)
|
||||||
|
BranchedValue.condJump(StackValue.onStack(condition.asmType), elseLabel, jumpIfFalse, mv)
|
||||||
}
|
}
|
||||||
|
|
||||||
val end = Label()
|
val end = Label()
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
// IGNORE_BACKEND: JVM_IR
|
||||||
// FILE: list.kt
|
// FILE: list.kt
|
||||||
|
|
||||||
val intList = listOf(1, 2, 3)
|
val intList = listOf(1, 2, 3)
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
val two = 2
|
val two = 2
|
||||||
|
|
||||||
fun test2() {
|
fun test2() {
|
||||||
|
|||||||
Reference in New Issue
Block a user