From fee58e98c5811aeabd789474ac4822043683bd88 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 3 Jul 2022 12:50:39 +0200 Subject: [PATCH] tiny optimization --- .../astprocessing/BeforeAsmAstChanger.kt | 35 +++++++++++++++++-- docs/source/todo.rst | 18 ++++++++-- 2 files changed, 49 insertions(+), 4 deletions(-) diff --git a/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt b/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt index 3fc37769d..8f7708306 100644 --- a/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt +++ b/compiler/src/prog8/compiler/astprocessing/BeforeAsmAstChanger.kt @@ -67,6 +67,10 @@ internal class BeforeAsmAstChanger(val program: Program, // Try to replace A = B Something by A= B, A = A Something // this triggers the more efficent augmented assignment code generation more often. // But it can only be done if the target variable IS NOT OCCURRING AS AN OPERAND ITSELF. + + if(options.compTarget.name==VMTarget.NAME) // don't apply this optimization for Vm target + return noModifications + if(!assignment.isAugmentable && assignment.target.identifier != null && !assignment.target.isIOAddress(options.compTarget.machine)) { @@ -170,8 +174,35 @@ internal class BeforeAsmAstChanger(val program: Program, override fun after(ifElse: IfElse, parent: Node): Iterable { val binExpr = ifElse.condition as? BinaryExpression - if(binExpr==null || binExpr.operator !in ComparisonOperators) { - // if x -> if x!=0, if x+5 -> if x+5 != 0 + if(binExpr==null) { + // if x -> if x!=0 + val booleanExpr = BinaryExpression( + ifElse.condition, + "!=", + NumericLiteral.optimalInteger(0, ifElse.condition.position), + ifElse.condition.position + ) + return listOf(IAstModification.ReplaceNode(ifElse.condition, booleanExpr, ifElse)) + } + + if(binExpr.operator !in ComparisonOperators) { + val constRight = binExpr.right.constValue(program) + if(constRight!=null) { + if (binExpr.operator == "+") { + // if x+5 -> if x != -5 + val number = NumericLiteral(constRight.type, -constRight.number, constRight.position) + val booleanExpr = BinaryExpression(binExpr.left,"!=", number, ifElse.condition.position) + return listOf(IAstModification.ReplaceNode(ifElse.condition, booleanExpr, ifElse)) + } + else if (binExpr.operator == "-") { + // if x-5 -> if x != 5 + val number = NumericLiteral(constRight.type, constRight.number, constRight.position) + val booleanExpr = BinaryExpression(binExpr.left,"!=", number, ifElse.condition.position) + return listOf(IAstModification.ReplaceNode(ifElse.condition, booleanExpr, ifElse)) + } + } + + // if x*5 -> if x*5 != 0 val booleanExpr = BinaryExpression( ifElse.condition, "!=", diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 134a7d9f1..32c2503fa 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,7 @@ TODO For next release ^^^^^^^^^^^^^^^^ -... +- bool data type? see below Need help with @@ -16,7 +16,6 @@ Need help with Future Things and Ideas ^^^^^^^^^^^^^^^^^^^^^^^ Compiler: -- add true 'bool' type that can only be 0 or 1, so that logical expressons don't have to use boolean() all the time on their operands - add some more optimizations in vmPeepholeOptimizer - vm Instruction needs to know what the read-registers/memory are, and what the write-register/memory is. this info is needed for more advanced optimizations and later code generation steps. @@ -80,6 +79,21 @@ Optimizations: - when a for loop's loopvariable isn't referenced in the body, and the iterations are known, replace the loop by a repeatloop but we have no efficient way right now to see if the body references a variable. +BOOL data type? +--------------- +Logical expressions now need to sprinkle boolean() calls on their operands to yield the correct boolean 0 or 1 result. +This is inefficient because most of the time the operands already are boolean but the compiler doesn't know this +because the type of boolean values is UBYTE (so theoretically the value can be anything from 0 - 255) + +So the idea is to add a true 'bool' type + +- add BOOL datatype +- add ARRAY_OF_BOOL array type +- assignments to it automatically do boolean() conversion +- logical expressions don't wrap operand of this type +- bool & 1 -> bool +- before codegen, bool type is discarded and it's just UBYTE + STRUCTS again? --------------