From 46ca0ac10dddfd8518b7e119f023c5d0550fb968 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sun, 5 Jun 2022 15:35:29 +0200 Subject: [PATCH] properly optimize X - -1 and X + -1, this also fixes type change of ubyte - 2 + 10 --- .../optimizer/ConstantFoldingOptimizer.kt | 15 ++ compiler/test/TestNumericLiteral.kt | 31 +++++ .../prog8/ast/expressions/AstExpressions.kt | 4 +- docs/source/todo.rst | 1 - examples/test.p8 | 131 +++++++++--------- 5 files changed, 116 insertions(+), 66 deletions(-) diff --git a/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt b/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt index ad8457ba7..d00f6a5d0 100644 --- a/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt +++ b/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt @@ -192,6 +192,21 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { modifications += IAstModification.ReplaceNode(expr, result, parent) } + if(leftconst==null && rightconst!=null && rightconst.number<0.0) { + if (expr.operator == "-") { + // X - -1 ---> X + 1 + val posNumber = NumericLiteral.optimalNumeric(-rightconst.number, rightconst.position) + val plusExpr = BinaryExpression(expr.left, "+", posNumber, expr.position) + return listOf(IAstModification.ReplaceNode(expr, plusExpr, parent)) + } + else if (expr.operator == "+") { + // X + -1 ---> X - 1 + val posNumber = NumericLiteral.optimalNumeric(-rightconst.number, rightconst.position) + val plusExpr = BinaryExpression(expr.left, "-", posNumber, expr.position) + return listOf(IAstModification.ReplaceNode(expr, plusExpr, parent)) + } + } + val leftBinExpr = expr.left as? BinaryExpression val rightBinExpr = expr.right as? BinaryExpression diff --git a/compiler/test/TestNumericLiteral.kt b/compiler/test/TestNumericLiteral.kt index 129187bc1..0838ae244 100644 --- a/compiler/test/TestNumericLiteral.kt +++ b/compiler/test/TestNumericLiteral.kt @@ -152,4 +152,35 @@ class TestNumericLiteral: FunSpec({ (NumericLiteral(DataType.FLOAT, 100.0, dummyPos) <= NumericLiteral(DataType.FLOAT, 99.9, dummyPos)) shouldBe false } + test("optimalInteger") { + NumericLiteral.optimalInteger(10, Position.DUMMY).type shouldBe DataType.UBYTE + NumericLiteral.optimalInteger(10, Position.DUMMY).number shouldBe 10.0 + NumericLiteral.optimalInteger(-10, Position.DUMMY).type shouldBe DataType.BYTE + NumericLiteral.optimalInteger(-10, Position.DUMMY).number shouldBe -10.0 + NumericLiteral.optimalInteger(1000, Position.DUMMY).type shouldBe DataType.UWORD + NumericLiteral.optimalInteger(-1000, Position.DUMMY).number shouldBe -1000.0 + NumericLiteral.optimalInteger(1000u, Position.DUMMY).type shouldBe DataType.UWORD + NumericLiteral.optimalInteger(1000u, Position.DUMMY).number shouldBe 1000.0 + } + + test("optimalNumeric") { + NumericLiteral.optimalNumeric(10, Position.DUMMY).type shouldBe DataType.UBYTE + NumericLiteral.optimalNumeric(10, Position.DUMMY).number shouldBe 10.0 + NumericLiteral.optimalNumeric(-10, Position.DUMMY).type shouldBe DataType.BYTE + NumericLiteral.optimalNumeric(-10, Position.DUMMY).number shouldBe -10.0 + NumericLiteral.optimalNumeric(1000, Position.DUMMY).type shouldBe DataType.UWORD + NumericLiteral.optimalNumeric(1000, Position.DUMMY).number shouldBe 1000.0 + NumericLiteral.optimalNumeric(-1000, Position.DUMMY).type shouldBe DataType.WORD + NumericLiteral.optimalNumeric(-1000, Position.DUMMY).number shouldBe -1000.0 + NumericLiteral.optimalNumeric(1.123, Position.DUMMY).type shouldBe DataType.FLOAT + NumericLiteral.optimalNumeric(1.123, Position.DUMMY).number shouldBe 1.123 + NumericLiteral.optimalNumeric(1.0, Position.DUMMY).type shouldBe DataType.UBYTE + NumericLiteral.optimalNumeric(1.0, Position.DUMMY).number shouldBe 1.0 + NumericLiteral.optimalNumeric(-1.0, Position.DUMMY).type shouldBe DataType.BYTE + NumericLiteral.optimalNumeric(-1.0, Position.DUMMY).number shouldBe -1.0 + NumericLiteral.optimalNumeric(1234.0, Position.DUMMY).type shouldBe DataType.UWORD + NumericLiteral.optimalNumeric(1234.0, Position.DUMMY).number shouldBe 1234.0 + NumericLiteral.optimalNumeric(-1234.0, Position.DUMMY).type shouldBe DataType.WORD + NumericLiteral.optimalNumeric(-1234.0, Position.DUMMY).number shouldBe -1234.0 + } }) diff --git a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt index e21a92df7..9353c4b6b 100644 --- a/compilerAst/src/prog8/ast/expressions/AstExpressions.kt +++ b/compilerAst/src/prog8/ast/expressions/AstExpressions.kt @@ -13,6 +13,7 @@ import prog8.ast.walk.IAstVisitor import prog8.code.core.* import java.util.* import kotlin.math.abs +import kotlin.math.floor import kotlin.math.round @@ -446,7 +447,8 @@ class NumericLiteral(val type: DataType, // only numerical types allowed NumericLiteral(DataType.UBYTE, if (bool) 1.0 else 0.0, position) fun optimalNumeric(value: Number, position: Position): NumericLiteral { - return if(value is Double) { + val digits = floor(value.toDouble()) - value.toDouble() + return if(value is Double && digits!=0.0) { NumericLiteral(DataType.FLOAT, value, position) } else { val dvalue = value.toDouble() diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 049a13bbe..1709291eb 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,7 +3,6 @@ TODO For next release ^^^^^^^^^^^^^^^^ -- fix natt's bug: ubyte - 2 + 10 somehow gets promoted to byte? - optimize pointervar indexing codegen: make them work as subroutine paramers - optimize pointervar indexing codegen: writing (all sorts of things) - pipe operator: (targets other than 'Virtual'): allow non-unary function calls in the pipe that specify the other argument(s) in the calls. Already working for VM target. diff --git a/examples/test.p8 b/examples/test.p8 index 2ca8e7bad..40719b66f 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -31,75 +31,78 @@ main { sub start() { ; mcCarthy() - uword uw = -2 - ubyte ub = -2 - uw = -2 as uword - ub = -2 as ubyte - txt.print_uw(uw) + uword uw1 = 9999 + uword uw2 = uw1 - 2000 + 10000 + ubyte ub1 = 99 + ubyte ub2 = ub1 - 2 + 10 + ubyte ubb = ub2 - -10 + txt.print_uw(uw2) txt.spc() - txt.print_ub(ub) + txt.print_ub(ub2) + txt.spc() + txt.print_ub(ubb) txt.nl() ;test_stack.test() - ubyte value = 0 - ubyte one = 1 - ubyte[10] data = [11,22,33,4,5,6,7,8,9,10] - uword bitmapbuf = &data - - value = bitmapbuf[2] - txt.print_ub(value) ;; 33 - txt.nl() - - ; 11 22 33 - txt.print_ub(bitmapbuf[0]) - txt.spc() - txt.print_ub(bitmapbuf[1]) - txt.spc() - txt.print_ub(bitmapbuf[2]) - txt.nl() - rol(bitmapbuf[0]) - rol(bitmapbuf[0]) - txt.print_ub(bitmapbuf[0]) ; 44 - txt.spc() - ror(bitmapbuf[0]) - ror(bitmapbuf[0]) - txt.print_ub(bitmapbuf[0]) ; 11 - txt.nl() - - ; 22 44 66 - txt.print_ub(bitmapbuf[0]*2) - txt.spc() - txt.print_ub(bitmapbuf[1]*2) - txt.spc() - txt.print_ub(bitmapbuf[2]*2) - txt.nl() - - value = one+one+one+one+one - txt.print_ub(value) ; 5 - txt.nl() - - bitmapbuf[0] = one - bitmapbuf[1] = one+one - bitmapbuf[2] = one+one+one - bitmapbuf[2] += 4 - bitmapbuf[2] -= 2 - bitmapbuf[2] -= 2 - swap(bitmapbuf[0], bitmapbuf[1]) - - ; 2 1 3 - txt.print_ub(bitmapbuf[0]) - txt.spc() - txt.print_ub(bitmapbuf[1]) - txt.spc() - txt.print_ub(bitmapbuf[2]) - txt.nl() - - for value in data { - txt.print_ub(value) - txt.spc() - } - txt.nl() +; ubyte value = 0 +; ubyte one = 1 +; ubyte[10] data = [11,22,33,4,5,6,7,8,9,10] +; uword bitmapbuf = &data +; +; value = bitmapbuf[2] +; txt.print_ub(value) ;; 33 +; txt.nl() +; +; ; 11 22 33 +; txt.print_ub(bitmapbuf[0]) +; txt.spc() +; txt.print_ub(bitmapbuf[1]) +; txt.spc() +; txt.print_ub(bitmapbuf[2]) +; txt.nl() +; rol(bitmapbuf[0]) +; rol(bitmapbuf[0]) +; txt.print_ub(bitmapbuf[0]) ; 44 +; txt.spc() +; ror(bitmapbuf[0]) +; ror(bitmapbuf[0]) +; txt.print_ub(bitmapbuf[0]) ; 11 +; txt.nl() +; +; ; 22 44 66 +; txt.print_ub(bitmapbuf[0]*2) +; txt.spc() +; txt.print_ub(bitmapbuf[1]*2) +; txt.spc() +; txt.print_ub(bitmapbuf[2]*2) +; txt.nl() +; +; value = one+one+one+one+one +; txt.print_ub(value) ; 5 +; txt.nl() +; +; bitmapbuf[0] = one +; bitmapbuf[1] = one+one +; bitmapbuf[2] = one+one+one +; bitmapbuf[2] += 4 +; bitmapbuf[2] -= 2 +; bitmapbuf[2] -= 2 +; swap(bitmapbuf[0], bitmapbuf[1]) +; +; ; 2 1 3 +; txt.print_ub(bitmapbuf[0]) +; txt.spc() +; txt.print_ub(bitmapbuf[1]) +; txt.spc() +; txt.print_ub(bitmapbuf[2]) +; txt.nl() +; +; for value in data { +; txt.print_ub(value) +; txt.spc() +; } +; txt.nl() ;test_stack.test()