From d2b63c8c311d4d89547cf04a46905c9317cf4d65 Mon Sep 17 00:00:00 2001 From: Zalim Bashorov Date: Tue, 15 Nov 2022 18:42:43 +0100 Subject: [PATCH] [Wasm] Use common logic for `eqeq` and `eqeqeq` So, now it generates better code when null literals are passed to `eqeqeq`, same as for `eqeq`. --- .../backend/wasm/lower/BuiltInsLowering.kt | 24 +++++++++++-------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt index 468b27a4d90..9ac1232e75c 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/lower/BuiltInsLowering.kt @@ -35,7 +35,7 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass { return klass.functions.single { it.isEqualsInheritedFromAny() } } - fun transformCall( + private fun transformCall( call: IrCall, builder: DeclarationIrBuilder ): IrExpression { @@ -52,7 +52,8 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass { } return irCall(call, symbols.floatEqualityFunctions.getValue(irBuiltins.doubleType)) } - irBuiltins.eqeqSymbol -> { + irBuiltins.eqeqSymbol, + irBuiltins.eqeqeqSymbol -> { fun callRefIsNull(expr: IrExpression): IrCall { val refIsNull = if (expr.type.erasedUpperBound?.isExternal == true) symbols.externRefIsNull else symbols.refIsNull return builder.irCall(refIsNull).apply { putValueArgument(0, expr) } @@ -67,23 +68,26 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass { val lhsType = lhs.type val rhsType = rhs.type + if (lhsType == rhsType) { - val newSymbol = symbols.equalityFunctions[lhsType] + val newSymbol = + symbols.equalityFunctions[lhsType] + // For eqeqeqSymbol try to use more efficient comparison if type is Double or Float. + // But for eqeqSymbol we have to use generic comparison for floating point numbers. + ?: if (call.symbol === irBuiltins.eqeqeqSymbol) symbols.floatEqualityFunctions[lhsType] else null + if (newSymbol != null) { return irCall(call, newSymbol) } } - if (!lhsType.isNullable()) { + // For eqeqSymbol use overridden `Any.equals(Any?)` if there is any. + if (call.symbol === irBuiltins.eqeqSymbol && !lhsType.isNullable()) { return irCall(call, lhsType.findEqualsMethod().symbol, argumentsAsReceivers = true) } - return irCall(call, symbols.nullableEquals) - } - irBuiltins.eqeqeqSymbol -> { - val type = call.getValueArgument(0)!!.type - val newSymbol = symbols.equalityFunctions[type] ?: symbols.floatEqualityFunctions[type] ?: symbols.refEq - return irCall(call, newSymbol) + val fallbackEqFun = if (call.symbol === irBuiltins.eqeqeqSymbol) symbols.refEq else symbols.nullableEquals + return irCall(call, fallbackEqFun) } irBuiltins.checkNotNullSymbol -> {