more Rpn optimizations

This commit is contained in:
Irmen de Jong 2023-03-18 18:25:08 +01:00
parent 9b971ad222
commit 52b560e72d
6 changed files with 46 additions and 34 deletions

View File

@ -204,7 +204,7 @@ class PtRpn(type: DataType, position: Position): PtExpression(type, position) {
return false return false
} }
fun maxDepth(): Pair<Map<DataType, Int>, Int> { fun maxDepth(): Map<DataType, Int> {
val depths = mutableMapOf( val depths = mutableMapOf(
DataType.UBYTE to 0, DataType.UBYTE to 0,
DataType.UWORD to 0, DataType.UWORD to 0,
@ -225,7 +225,7 @@ class PtRpn(type: DataType, position: Position): PtExpression(type, position) {
depths[DataType.UBYTE] = depth depths[DataType.UBYTE] = depth
maxDepths[DataType.UBYTE] = max(maxDepths.getValue(DataType.UBYTE), depth) maxDepths[DataType.UBYTE] = max(maxDepths.getValue(DataType.UBYTE), depth)
} }
in WordDatatypes -> { in WordDatatypes, in PassByReferenceDatatypes -> {
val depth = depths.getValue(DataType.UWORD) + 1 val depth = depths.getValue(DataType.UWORD) + 1
depths[DataType.UWORD] = depth depths[DataType.UWORD] = depth
maxDepths[DataType.UWORD] = max(maxDepths.getValue(DataType.UWORD), depth) maxDepths[DataType.UWORD] = max(maxDepths.getValue(DataType.UWORD), depth)
@ -243,7 +243,7 @@ class PtRpn(type: DataType, position: Position): PtExpression(type, position) {
fun pop(type: DataType) { fun pop(type: DataType) {
when (type) { when (type) {
in ByteDatatypes -> depths[DataType.UBYTE]=depths.getValue(DataType.UBYTE) - 1 in ByteDatatypes -> depths[DataType.UBYTE]=depths.getValue(DataType.UBYTE) - 1
in WordDatatypes -> depths[DataType.UWORD]=depths.getValue(DataType.UWORD) - 1 in WordDatatypes, in PassByReferenceDatatypes -> depths[DataType.UWORD]=depths.getValue(DataType.UWORD) - 1
DataType.FLOAT -> depths[DataType.FLOAT]=depths.getValue(DataType.FLOAT) - 1 DataType.FLOAT -> depths[DataType.FLOAT]=depths.getValue(DataType.FLOAT) - 1
else -> throw IllegalArgumentException("invalid dt") else -> throw IllegalArgumentException("invalid dt")
} }
@ -260,10 +260,10 @@ class PtRpn(type: DataType, position: Position): PtExpression(type, position) {
push((node as PtExpression).type) push((node as PtExpression).type)
} }
} }
require(numPushes==numPops+1) { require(numPushes==numPops+1 && numPushes==children.size) {
"RPN not balanced, pushes=$numPushes pops=$numPops" "RPN not balanced, pushes=$numPushes pops=$numPops childs=${children.size}"
} }
return Pair(maxDepths, numPushes) return maxDepths
} }
fun finalOperator() = children.last() as PtRpnOperator fun finalOperator() = children.last() as PtRpnOperator

View File

@ -1013,8 +1013,29 @@ $repeatLabel lda $counterVar
when (pointerOffsetExpr) { when (pointerOffsetExpr) {
is PtRpn -> { is PtRpn -> {
if(pointerOffsetExpr.children.size>3) { if(pointerOffsetExpr.children.size>3) {
println("TODO: RPN: too complicated pointerViaIndexRegisterPossible") // TODO RPN: split expression? val rightmostOperator = pointerOffsetExpr.finalOperator()
return null // expression is too complex, we need just a pointer var + index if(rightmostOperator.operator=="+") {
val rightmostOperand = pointerOffsetExpr.finalRightOperand()
if ((rightmostOperand is PtNumber && rightmostOperand.type in IntegerDatatypes && rightmostOperand.number.toInt() in 0..255)
|| (rightmostOperand is PtExpression && rightmostOperand.type == DataType.UBYTE)
|| (rightmostOperand is PtTypeCast && rightmostOperand.value.type == DataType.UBYTE)
) {
// split up the big expression in 2 parts so that we CAN use ZP,Y indexing after all
pointerOffsetExpr.children.removeLast()
pointerOffsetExpr.children.removeLast()
val tempvar = getTempVarName(DataType.UWORD)
assignExpressionToVariable(pointerOffsetExpr, tempvar, DataType.UWORD, pointerOffsetExpr.definingISub())
val smallExpr = PtRpn(DataType.UWORD, pointerOffsetExpr.position)
smallExpr.addRpnNode(PtIdentifier(tempvar, DataType.UWORD, pointerOffsetExpr.position))
smallExpr.addRpnNode(rightmostOperand)
smallExpr.addRpnNode(rightmostOperator)
smallExpr.parent = pointerOffsetExpr.parent
val result = pointerViaIndexRegisterPossible(smallExpr)
require(result != null)
return result
}
}
return null // expression is too complex
} }
val (leftNode, oper, rightNode) = pointerOffsetExpr.finalOperation() val (leftNode, oper, rightNode) = pointerOffsetExpr.finalOperation()
operator=oper.operator operator=oper.operator
@ -2910,9 +2931,7 @@ $repeatLabel lda $counterVar
} }
is PtRpn -> { is PtRpn -> {
val addrExpr = expr.address as PtRpn val addrExpr = expr.address as PtRpn
if(addrExpr.children.size>3) if(tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) {
println("TODO: RPN: too complicated translateDirectMemReadExpressionToRegAorStack") // TODO RPN: split expression?
if(addrExpr.children.size==3 && tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) {
if(pushResultOnEstack) if(pushResultOnEstack)
out(" sta P8ESTACK_LO,x | dex") out(" sta P8ESTACK_LO,x | dex")
} else { } else {

View File

@ -146,9 +146,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
is PtRpn -> { is PtRpn -> {
val addrExpr = value.address as PtRpn val addrExpr = value.address as PtRpn
if(addrExpr.children.size>3) if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) {
println("TODO: RPN: too complex translateNormalAssignment") // TODO RPN: split expression?
if(addrExpr.children.size==3 && asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) {
assignRegisterByte(assign.target, CpuRegister.A) assignRegisterByte(assign.target, CpuRegister.A)
} else { } else {
assignViaExprEval(value.address) assignViaExprEval(value.address)
@ -926,10 +924,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
} }
is PtRpn -> { is PtRpn -> {
val addrExpr = value.address as PtRpn val addrExpr = value.address as PtRpn
if(addrExpr.children.size>3) { if(asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) {
println("TODO: RPN: too complex assignTypeCastedValue") // TODO RPN : split expression?
}
if(addrExpr.children.size==3 && asmgen.tryOptimizedPointerAccessWithA(addrExpr, addrExpr.finalOperator().operator, false)) {
asmgen.out(" ldy #0") asmgen.out(" ldy #0")
assignRegisterpairWord(target, RegisterOrPair.AY) assignRegisterpairWord(target, RegisterOrPair.AY)
} else { } else {
@ -2859,9 +2854,7 @@ internal class AssignmentAsmGen(private val program: PtProgram,
asmgen.storeAIntoPointerVar(addressExpr) asmgen.storeAIntoPointerVar(addressExpr)
} }
addressExpr is PtRpn -> { addressExpr is PtRpn -> {
if(addressExpr.children.size>3) if(!asmgen.tryOptimizedPointerAccessWithA(addressExpr, addressExpr.finalOperator().operator, true))
println("TODO: RPN: too complex storeRegisterAInMemoryAddress $memoryAddress") // TODO RPN: split expression?
if(addressExpr.children.size!=3 || !asmgen.tryOptimizedPointerAccessWithA(addressExpr, addressExpr.finalOperator().operator, true))
storeViaExprEval() storeViaExprEval()
} }
addressExpr is PtBinaryExpression -> { addressExpr is PtBinaryExpression -> {

View File

@ -13,7 +13,7 @@ internal class RpnExpressionAsmGen(
fun attemptAssignOptimizedExpr(assign: AsmAssignment): Boolean { fun attemptAssignOptimizedExpr(assign: AsmAssignment): Boolean {
val value = assign.source.expression as PtRpn val value = assign.source.expression as PtRpn
println("TODO: RPN: optimized assignment ${value.position}") // TODO RPN: optimized assignment println("TODO: RPN: optimized assignment ${value.position} maxdepth=${value.maxDepth()}") // TODO RPN: optimized assignment
// NOTE: don't forgot to evaluate the rest of the RPN expr as well // NOTE: don't forgot to evaluate the rest of the RPN expr as well
return false return false
} }

View File

@ -1,9 +1,9 @@
TODO TODO
==== ====
BRANCH: Write some unit tests for the RPN.
BRANCH: Fix the TODO RPN routines to be optimized assembly in RpnExpressionAsmGen.kt BRANCH: Fix the TODO RPN routines to be optimized assembly in RpnExpressionAsmGen.kt
BRANCH: Implement RPN codegen for IR.
Implement RPN codegen for IR.
For next minor release For next minor release
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^

View File

@ -8,17 +8,18 @@
main { main {
sub start() { sub start() {
test_stack.test()
uword xx=4000 uword xx=4000
ubyte a ubyte a=11
ubyte b ubyte b=22
ubyte c ubyte c=33
ubyte d
cx16.r0 = peekw(xx+42) ; cx16.r0 = peekw(xx+a+b+c)
; TODO cx16.r0 = peekw(a+xx+b+c+d+) ; cx16.r1 = peekw(xx+a+b+c+42)
; TODO @(a+xx+b+c+d) = cx16.r0L ; pokew(xx+a+b+c, xx)
; pokew(xx+a+b+c+42, xx)
if a and a & $40 == 0
cx16.r0++
; if cx16.r0L in "derp" { ; if cx16.r0L in "derp" {
; xx++ ; xx++
@ -26,7 +27,6 @@ main {
; ;
; xx = xx+(3*func(xx)+xx*2*cx16.r0L) ; xx = xx+(3*func(xx)+xx*2*cx16.r0L)
; txt.print_uw(xx) ; txt.print_uw(xx)
test_stack.test()
} }
; sub func(uword value) -> uword { ; sub func(uword value) -> uword {