From 7dd758a75339d84e5749893238385450ceb33913 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 6 Jan 2024 21:47:59 +0100 Subject: [PATCH] better optimize WORD & $xx00 , WORD & $00xx --- .../prog8/optimizer/ExpressionSimplifier.kt | 52 ++++++++++++++++--- examples/test.p8 | 44 +++++++++++----- 2 files changed, 75 insertions(+), 21 deletions(-) diff --git a/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt b/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt index 0a4ef859b..b4f450c00 100644 --- a/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt +++ b/codeOptimizers/src/prog8/optimizer/ExpressionSimplifier.kt @@ -13,7 +13,6 @@ import prog8.ast.statements.Jump import prog8.ast.walk.AstWalker import prog8.ast.walk.IAstModification import prog8.code.core.* -import prog8.code.target.VMTarget import kotlin.math.abs import kotlin.math.log2 import kotlin.math.pow @@ -76,18 +75,26 @@ class ExpressionSimplifier(private val program: Program, } } - if(compTarget.name!=VMTarget.NAME) { - val booleanCondition = ifElse.condition as? BinaryExpression - if(booleanCondition!=null && booleanCondition.operator=="&") { - // special optimization of WORD & $ff00 -> just and the msb of WORD with $ff - val rightNum = booleanCondition.right as? NumericLiteral - if(rightNum!=null && rightNum.type==DataType.UWORD && (rightNum.number.toInt() and 0x00ff)==0) { + val booleanCondition = ifElse.condition as? BinaryExpression + if(booleanCondition!=null && booleanCondition.operator=="&") { + val rightNum = booleanCondition.right as? NumericLiteral + if (rightNum!=null && rightNum.type==DataType.UWORD) { + if ((rightNum.number.toInt() and 0x00ff) == 0) { + // if WORD & $xx00 -> if msb(WORD) & $xx val msb = BuiltinFunctionCall(IdentifierReference(listOf("msb"), booleanCondition.left.position), mutableListOf(booleanCondition.left), booleanCondition.left.position) val bytevalue = NumericLiteral(DataType.UBYTE, (rightNum.number.toInt() shr 8).toDouble(), booleanCondition.right.position) return listOf( IAstModification.ReplaceNode(booleanCondition.left, msb, booleanCondition), IAstModification.ReplaceNode(booleanCondition.right, bytevalue, booleanCondition)) } + else if ((rightNum.number.toInt() and 0xff00) == 0) { + // if WORD & $00ff -> if lsb(WORD) & $ff + val lsb = BuiltinFunctionCall(IdentifierReference(listOf("lsb"), booleanCondition.left.position), mutableListOf(booleanCondition.left), booleanCondition.left.position) + val bytevalue = NumericLiteral(DataType.UBYTE, rightNum.number, booleanCondition.right.position) + return listOf( + IAstModification.ReplaceNode(booleanCondition.left, lsb, booleanCondition), + IAstModification.ReplaceNode(booleanCondition.right, bytevalue, booleanCondition)) + } } } @@ -331,6 +338,37 @@ class ExpressionSimplifier(private val program: Program, if(newExpr2 != null) return listOf(IAstModification.ReplaceNode(expr, newExpr2, parent)) + if (rightVal!=null && (expr.operator == "==" || expr.operator == "!=")) { + val bitwise = expr.left as? BinaryExpression + if(bitwise!=null && bitwise.operator=="&" && bitwise.inferType(program).isWords) { + val andNum = (bitwise.right as? NumericLiteral)?.number?.toInt() + if (andNum!=null) { + if ((andNum and 0x00ff) == 0) { + // (WORD & $xx00)==y -> (msb(WORD) & $xx)==y + val msb = BuiltinFunctionCall(IdentifierReference(listOf("msb"), bitwise.left.position), mutableListOf(bitwise.left), bitwise.left.position) + val bytevalue = NumericLiteral(DataType.UBYTE, (andNum shr 8).toDouble(), bitwise.right.position) + val rightvalByte = NumericLiteral(DataType.UBYTE, (rightVal.number.toInt() shr 8).toDouble(), rightVal.position) + return listOf( + IAstModification.ReplaceNode(bitwise.left, msb, bitwise), + IAstModification.ReplaceNode(bitwise.right, bytevalue, bitwise), + IAstModification.ReplaceNode(expr.right, rightvalByte, expr) + ) + } + else if((andNum and 0xff00) == 0) { + // (WORD & $00xx)==y -> (lsb(WORD) & $xx)==y + val lsb = BuiltinFunctionCall(IdentifierReference(listOf("lsb"), bitwise.left.position), mutableListOf(bitwise.left), bitwise.left.position) + val bytevalue = NumericLiteral(DataType.UBYTE, andNum.toDouble(), bitwise.right.position) + val rightvalByte = NumericLiteral(DataType.UBYTE, (rightVal.number.toInt() and 255).toDouble(), rightVal.position) + return listOf( + IAstModification.ReplaceNode(bitwise.left, lsb, bitwise), + IAstModification.ReplaceNode(bitwise.right, bytevalue, bitwise), + IAstModification.ReplaceNode(expr.right, rightvalByte, expr) + ) + } + } + } + } + return noModifications } diff --git a/examples/test.p8 b/examples/test.p8 index 9af8260c2..5ab398303 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -5,22 +5,38 @@ main { sub start() { - str s = "the quick brown fox jumps over the lazy dog." - uword sp = &s + uword @shared uw = $3f2f - cbm.SETTIM(0,0,0) - repeat 5000 { - cx16.r0L = 'v' in s - } - txt.print_uw(cbm.RDTIM16()) - txt.nl() + if uw & $0800 + txt.print("ok1\n") - cbm.SETTIM(0,0,0) - repeat 5000 { - cx16.r0L = string.contains(s, 'v') - } - txt.print_uw(cbm.RDTIM16()) - txt.nl() + if uw & 8 + txt.print("ok2\n") + if uw & $0800 ==0 + txt.print("fail1\n") + + if uw & $0800 !=0 + txt.print("ok3\n") + + if uw & 8 ==0 + txt.print("fail2\n") + + if uw & 8 !=0 + txt.print("ok4\n") + + + + if uw & $ff00 == $3f00 + txt.print("ok5\n") + + if uw & $ff00 != $3f00 + txt.print("fail5\n") + + if uw & $00ff == $002f + txt.print("ok6\n") + + if uw & $00ff != $002f + txt.print("fail6\n") } }