[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`.
This commit is contained in:
+14
-10
@@ -35,7 +35,7 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass {
|
|||||||
return klass.functions.single { it.isEqualsInheritedFromAny() }
|
return klass.functions.single { it.isEqualsInheritedFromAny() }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun transformCall(
|
private fun transformCall(
|
||||||
call: IrCall,
|
call: IrCall,
|
||||||
builder: DeclarationIrBuilder
|
builder: DeclarationIrBuilder
|
||||||
): IrExpression {
|
): IrExpression {
|
||||||
@@ -52,7 +52,8 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass {
|
|||||||
}
|
}
|
||||||
return irCall(call, symbols.floatEqualityFunctions.getValue(irBuiltins.doubleType))
|
return irCall(call, symbols.floatEqualityFunctions.getValue(irBuiltins.doubleType))
|
||||||
}
|
}
|
||||||
irBuiltins.eqeqSymbol -> {
|
irBuiltins.eqeqSymbol,
|
||||||
|
irBuiltins.eqeqeqSymbol -> {
|
||||||
fun callRefIsNull(expr: IrExpression): IrCall {
|
fun callRefIsNull(expr: IrExpression): IrCall {
|
||||||
val refIsNull = if (expr.type.erasedUpperBound?.isExternal == true) symbols.externRefIsNull else symbols.refIsNull
|
val refIsNull = if (expr.type.erasedUpperBound?.isExternal == true) symbols.externRefIsNull else symbols.refIsNull
|
||||||
return builder.irCall(refIsNull).apply { putValueArgument(0, expr) }
|
return builder.irCall(refIsNull).apply { putValueArgument(0, expr) }
|
||||||
@@ -67,23 +68,26 @@ class BuiltInsLowering(val context: WasmBackendContext) : FileLoweringPass {
|
|||||||
|
|
||||||
val lhsType = lhs.type
|
val lhsType = lhs.type
|
||||||
val rhsType = rhs.type
|
val rhsType = rhs.type
|
||||||
|
|
||||||
if (lhsType == rhsType) {
|
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) {
|
if (newSymbol != null) {
|
||||||
return irCall(call, newSymbol)
|
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, lhsType.findEqualsMethod().symbol, argumentsAsReceivers = true)
|
||||||
}
|
}
|
||||||
return irCall(call, symbols.nullableEquals)
|
|
||||||
}
|
|
||||||
|
|
||||||
irBuiltins.eqeqeqSymbol -> {
|
val fallbackEqFun = if (call.symbol === irBuiltins.eqeqeqSymbol) symbols.refEq else symbols.nullableEquals
|
||||||
val type = call.getValueArgument(0)!!.type
|
return irCall(call, fallbackEqFun)
|
||||||
val newSymbol = symbols.equalityFunctions[type] ?: symbols.floatEqualityFunctions[type] ?: symbols.refEq
|
|
||||||
return irCall(call, newSymbol)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
irBuiltins.checkNotNullSymbol -> {
|
irBuiltins.checkNotNullSymbol -> {
|
||||||
|
|||||||
Reference in New Issue
Block a user