From abca6180085ee689331d373557f147b9f935241c Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Thu, 9 Dec 2021 23:12:12 +0100 Subject: [PATCH] added more constfolding --- .../optimizer/ConstantFoldingOptimizer.kt | 29 +++++++++++--- compiler/test/TestOptimization.kt | 40 ++++++++++++++++++- examples/test.p8 | 24 +++-------- 3 files changed, 69 insertions(+), 24 deletions(-) diff --git a/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt b/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt index 984af6471..c98ba260f 100644 --- a/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt +++ b/codeOptimizers/src/prog8/optimizer/ConstantFoldingOptimizer.kt @@ -197,9 +197,9 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { val leftBinExpr = expr.left as? BinaryExpression val rightBinExpr = expr.right as? BinaryExpression - if(expr.operator=="+" || expr.operator=="-") { - if(leftBinExpr!=null && rightconst!=null) { + if(leftBinExpr!=null && rightconst!=null) { + if(expr.operator=="+" || expr.operator=="-") { if(leftBinExpr.operator in listOf("+", "-")) { val c2 = leftBinExpr.right.constValue(program) if(c2!=null) { @@ -211,10 +211,30 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { return listOf(IAstModification.ReplaceNode(expr, newExpr, parent)) } } - // TODO SAME FOR (X * C1) * C2 --> X * (C1*C2) - // TODO SAME FOR (X / C1) / C2 --> X / (C1*C2) } + else if(expr.operator=="*" && leftBinExpr.operator=="*") { + val c2 = leftBinExpr.right.constValue(program) + if(c2!=null) { + // (X * C1) * C2 --> X * (C1*C2) + // TODO (X * C1) / C2 --> X * (C1/C2) + val constants = BinaryExpression(c2, "*", rightconst, c2.position) + val newExpr = BinaryExpression(leftBinExpr.left, "*", constants, expr.position) + return listOf(IAstModification.ReplaceNode(expr, newExpr, parent)) + } + } + else if(expr.operator=="/" && leftBinExpr.operator=="/") { + val c2 = leftBinExpr.right.constValue(program) + if(c2!=null) { + // (X / C1) / C2 --> X / (C1*C2) + // TODO (X / C1) * C2 --> X * (C2/C1) + val constants = BinaryExpression(c2, "*", rightconst, c2.position) + val newExpr = BinaryExpression(leftBinExpr.left, "/", constants, expr.position) + return listOf(IAstModification.ReplaceNode(expr, newExpr, parent)) + } + } + } + if(expr.operator=="+" || expr.operator=="-") { if(leftBinExpr!=null && rightBinExpr!=null) { val c1 = leftBinExpr.right.constValue(program) val c2 = rightBinExpr.right.constValue(program) @@ -248,7 +268,6 @@ class ConstantFoldingOptimizer(private val program: Program) : AstWalker() { } - return modifications } diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index 10412fce6..c35ee174d 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -123,7 +123,6 @@ class TestOptimization: FunSpec({ } }""" val result = compileText(C64Target, true, source, writeAssembly = false).assertSuccess() - printProgram(result.program) // expected: // uword load_location // load_location = 12345 @@ -164,6 +163,45 @@ class TestOptimization: FunSpec({ binexpr7.right shouldBe NumericLiteralValue(DataType.UWORD, 99.0, Position.DUMMY) } + test("const folding multiple scenarios * and /") { + val source = """ + main { + sub start() { + ; TODO other variants of this const folding + word llw = 300 + cx16.r0s = 9 * 2 * 10 * llw + cx16.r1s = llw * 9 * 2 * 10 + cx16.r2s = llw / 20 / 3 + } + }""" + val result = compileText(C64Target, true, source, writeAssembly = false).assertSuccess() + printProgram(result.program) + // expected: +// word llw +// llw = 300 +// cx16.r0s = llw +// cx16.r0s *= 180 +// cx16.r1s = llw +// cx16.r1s *= 180 +// cx16.r2s = llw +// cx16.r2s /= 100 + val stmts = result.program.entrypoint.statements + stmts.size shouldBe 8 + + val mulR0Value = (stmts[3] as Assignment).value + val binexpr0 = mulR0Value as BinaryExpression + binexpr0.operator shouldBe "*" + binexpr0.right shouldBe NumericLiteralValue(DataType.UWORD, 180.0, Position.DUMMY) + val mulR1Value = (stmts[5] as Assignment).value + val binexpr1 = mulR1Value as BinaryExpression + binexpr1.operator shouldBe "*" + binexpr1.right shouldBe NumericLiteralValue(DataType.UWORD, 180.0, Position.DUMMY) + val divR2Value = (stmts[7] as Assignment).value + val binexpr2 = divR2Value as BinaryExpression + binexpr2.operator shouldBe "/" + binexpr2.right shouldBe NumericLiteralValue(DataType.UWORD, 60.0, Position.DUMMY) + } + test("constantfolded and silently typecasted for initializervalues") { val sourcecode = """ main { diff --git a/examples/test.p8 b/examples/test.p8 index 9c0b3635d..31f060482 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -4,23 +4,11 @@ main { sub start() { ; TODO other variants of this const folding - uword load_location = $6000 - word llw = $6000 - - cx16.r0 = load_location + 9000 + 1000 + 1000 - cx16.r1L = @(load_location + 8000 + 1000 + 1000) - cx16.r2 = 8000 + 1000 + 1000 + load_location - cx16.r3L = @(8000 + 1000 + 1000 + load_location) - - cx16.r0s = llw - 900 + 999 - cx16.r1L = @(llw - 900 + 999) - cx16.r0s = llw - 900 + 999 - cx16.r1L = @(llw - 9000 + 999) - - cx16.r0s = llw - 900 - 999 - cx16.r1L = @(llw - 900 - 999) - cx16.r0s = llw - 900 - 999 - cx16.r1L = @(llw - 9000 - 999) - + word llw = 300 + cx16.r0s = 9 * 2 * 10 * llw + cx16.r1s = llw * 9 * 2 * 10 + cx16.r2s = llw * 9 / 4 + cx16.r3s = llw / 20 / 5 + cx16.r4s = llw / 20 * 5 } }