Use primitive ops for mixed int/real

This commit is contained in:
Sergey Chernov 2026-02-16 17:37:49 +03:00
parent e8f5c9eaf4
commit 3e654ddd60
2 changed files with 8 additions and 20 deletions

View File

@ -1374,23 +1374,6 @@ class BytecodeCompiler(
val rightRef = binaryRight(ref)
var a = compileRefWithFallback(leftRef, null, refPos(ref)) ?: return null
var b = compileRefWithFallback(rightRef, null, refPos(ref)) ?: return null
if (op in setOf(BinOp.PLUS, BinOp.MINUS, BinOp.STAR, BinOp.SLASH, BinOp.PERCENT)) {
val leftNeedsObj = a.type == SlotType.INT && b.type == SlotType.REAL
val rightNeedsObj = b.type == SlotType.INT && a.type == SlotType.REAL
if (leftNeedsObj || rightNeedsObj) {
val leftObj = if (leftNeedsObj) {
compileScopeSlotObj(leftRef) ?: a
} else {
a
}
val rightObj = if (rightNeedsObj) {
compileScopeSlotObj(rightRef) ?: b
} else {
b
}
return compileObjBinaryOp(leftRef, leftObj, rightObj, op, refPos(ref))
}
}
val intOps = setOf(
BinOp.PLUS, BinOp.MINUS, BinOp.STAR, BinOp.SLASH, BinOp.PERCENT,
BinOp.BAND, BinOp.BOR, BinOp.BXOR, BinOp.SHL, BinOp.SHR
@ -1413,7 +1396,11 @@ class BytecodeCompiler(
}
val typesMismatch = a.type != b.type && a.type != SlotType.UNKNOWN && b.type != SlotType.UNKNOWN
val allowMixedNumeric = op in setOf(BinOp.PLUS, BinOp.MINUS, BinOp.STAR, BinOp.SLASH)
if (typesMismatch && op in setOf(BinOp.PLUS, BinOp.MINUS, BinOp.STAR, BinOp.SLASH, BinOp.PERCENT)) {
val isMixedNumeric = (a.type == SlotType.INT && b.type == SlotType.REAL) ||
(a.type == SlotType.REAL && b.type == SlotType.INT)
if (typesMismatch && op in setOf(BinOp.PLUS, BinOp.MINUS, BinOp.STAR, BinOp.SLASH, BinOp.PERCENT) &&
!(allowMixedNumeric && isMixedNumeric)
) {
return compileObjBinaryOp(leftRef, a, b, op, refPos(ref))
}
if ((a.type == SlotType.UNKNOWN || b.type == SlotType.UNKNOWN) &&

View File

@ -7,8 +7,9 @@ Candidates (not started)
1) Primitive comparisons (done)
- Emit fast CMP variants for known ObjString/ObjInt/ObjReal using temp/stable slots.
- MixedCompareBenchmarkTest: 374 ms -> 347 ms.
2) Mixed numeric ops
- Ensure INT+REAL arithmetic uses INT_TO_REAL + REAL op with no extra moves/boxing.
2) Mixed numeric ops (done)
- Allow INT+REAL arithmetic to use primitive REAL ops (no obj fallback).
- MixedCompareBenchmarkTest: 347 ms -> 275 ms.
3) Boolean conversion
- Skip OBJ_TO_BOOL when compiler already has a BOOL slot.
4) Range/loop hot path