Use primitive ops for mixed int/real
This commit is contained in:
parent
e8f5c9eaf4
commit
3e654ddd60
@ -1374,23 +1374,6 @@ class BytecodeCompiler(
|
|||||||
val rightRef = binaryRight(ref)
|
val rightRef = binaryRight(ref)
|
||||||
var a = compileRefWithFallback(leftRef, null, refPos(ref)) ?: return null
|
var a = compileRefWithFallback(leftRef, null, refPos(ref)) ?: return null
|
||||||
var b = compileRefWithFallback(rightRef, 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(
|
val intOps = setOf(
|
||||||
BinOp.PLUS, BinOp.MINUS, BinOp.STAR, BinOp.SLASH, BinOp.PERCENT,
|
BinOp.PLUS, BinOp.MINUS, BinOp.STAR, BinOp.SLASH, BinOp.PERCENT,
|
||||||
BinOp.BAND, BinOp.BOR, BinOp.BXOR, BinOp.SHL, BinOp.SHR
|
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 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)
|
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))
|
return compileObjBinaryOp(leftRef, a, b, op, refPos(ref))
|
||||||
}
|
}
|
||||||
if ((a.type == SlotType.UNKNOWN || b.type == SlotType.UNKNOWN) &&
|
if ((a.type == SlotType.UNKNOWN || b.type == SlotType.UNKNOWN) &&
|
||||||
|
|||||||
@ -7,8 +7,9 @@ Candidates (not started)
|
|||||||
1) Primitive comparisons (done)
|
1) Primitive comparisons (done)
|
||||||
- Emit fast CMP variants for known ObjString/ObjInt/ObjReal using temp/stable slots.
|
- Emit fast CMP variants for known ObjString/ObjInt/ObjReal using temp/stable slots.
|
||||||
- MixedCompareBenchmarkTest: 374 ms -> 347 ms.
|
- MixedCompareBenchmarkTest: 374 ms -> 347 ms.
|
||||||
2) Mixed numeric ops
|
2) Mixed numeric ops (done)
|
||||||
- Ensure INT+REAL arithmetic uses INT_TO_REAL + REAL op with no extra moves/boxing.
|
- Allow INT+REAL arithmetic to use primitive REAL ops (no obj fallback).
|
||||||
|
- MixedCompareBenchmarkTest: 347 ms -> 275 ms.
|
||||||
3) Boolean conversion
|
3) Boolean conversion
|
||||||
- Skip OBJ_TO_BOOL when compiler already has a BOOL slot.
|
- Skip OBJ_TO_BOOL when compiler already has a BOOL slot.
|
||||||
4) Range/loop hot path
|
4) Range/loop hot path
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user