Return an immaterial value from Boolean.not
This commit is contained in:
+2
-22
@@ -702,7 +702,7 @@ class ExpressionCodegen(
|
||||
if (branch.condition.isFalseConst())
|
||||
continue // The branch body is dead code.
|
||||
} else {
|
||||
genConditionalJumpWithOptimizationsIfPossible(branch.condition, data, elseLabel)
|
||||
BranchedValue.condJump(branch.condition.accept(this, data), elseLabel, true, mv)
|
||||
}
|
||||
val result = branch.result.accept(this, data).coerce(expression.type).materializeNonUnit()
|
||||
if (branch.condition.isTrueConst()) {
|
||||
@@ -720,26 +720,6 @@ class ExpressionCodegen(
|
||||
return result
|
||||
}
|
||||
|
||||
private fun genConditionalJumpWithOptimizationsIfPossible(
|
||||
originalCondition: IrExpression,
|
||||
data: BlockInfo,
|
||||
jumpToLabel: Label,
|
||||
originalJumpIfFalse: Boolean = true
|
||||
) {
|
||||
var condition = originalCondition
|
||||
var jumpIfFalse = originalJumpIfFalse
|
||||
|
||||
// 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.
|
||||
if (isNegation(condition, classCodegen.context)) {
|
||||
condition = (condition as IrCall).dispatchReceiver!!
|
||||
jumpIfFalse = !jumpIfFalse
|
||||
}
|
||||
|
||||
BranchedValue.condJump(condition.accept(this, data), jumpToLabel, jumpIfFalse, mv)
|
||||
}
|
||||
|
||||
override fun visitTypeOperator(expression: IrTypeOperatorCall, data: BlockInfo): StackValue {
|
||||
val kotlinType = expression.typeOperand.toKotlinType()
|
||||
val asmType = kotlinType.asmType
|
||||
@@ -863,7 +843,7 @@ class ExpressionCodegen(
|
||||
mv.fakeAlwaysTrueIfeq(label)
|
||||
}
|
||||
} else {
|
||||
genConditionalJumpWithOptimizationsIfPossible(condition, data, label, jumpIfFalse)
|
||||
BranchedValue.condJump(condition.accept(this, data), label, jumpIfFalse, mv)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -17,20 +17,22 @@
|
||||
package org.jetbrains.kotlin.backend.jvm.intrinsics
|
||||
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.codegen.Callable
|
||||
import org.jetbrains.kotlin.codegen.CallableMethod
|
||||
import org.jetbrains.kotlin.codegen.ExpressionCodegen
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.BlockInfo
|
||||
import org.jetbrains.kotlin.codegen.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrMemberAccessExpression
|
||||
import org.jetbrains.kotlin.psi.KtPrefixExpression
|
||||
import org.jetbrains.kotlin.resolve.calls.model.ResolvedCall
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
class Not : IntrinsicMethod() {
|
||||
override fun toCallable(expression: IrMemberAccessExpression, signature: JvmMethodSignature, context: JvmBackendContext): IrIntrinsicFunction {
|
||||
return IrIntrinsicFunction.create(expression, signature, context) {
|
||||
StackValue.not(StackValue.onStack(Type.BOOLEAN_TYPE)).put(it)
|
||||
return object : IrIntrinsicFunction(expression, signature, context, expression.argTypes(context)) {
|
||||
override fun invoke(
|
||||
v: InstructionAdapter,
|
||||
codegen: org.jetbrains.kotlin.backend.jvm.codegen.ExpressionCodegen,
|
||||
data: BlockInfo
|
||||
): StackValue = StackValue.not(expression.dispatchReceiver!!.accept(codegen, data))
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user