From 67b0890a6e5a4f70881d564c82108f0d2eaaa21b Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Sat, 25 Dec 2021 23:30:09 +0100 Subject: [PATCH] remove unneeded var inits when an assignment is already present --- compiler/src/prog8/compiler/Compiler.kt | 4 ++-- .../prog8/compiler/astprocessing/StatementReorderer.kt | 8 ++++++++ compiler/test/TestOptimization.kt | 7 ++++--- compiler/test/TestSubroutines.kt | 6 +++--- examples/test.p8 | 8 ++++++++ 5 files changed, 25 insertions(+), 8 deletions(-) diff --git a/compiler/src/prog8/compiler/Compiler.kt b/compiler/src/prog8/compiler/Compiler.kt index 9f90b282b..3df6c6324 100644 --- a/compiler/src/prog8/compiler/Compiler.kt +++ b/compiler/src/prog8/compiler/Compiler.kt @@ -76,8 +76,8 @@ fun compileProgram(args: CompilerArguments): CompilationResult { ) postprocessAst(program, args.errors, compilationOptions) - println("*********** AST BEFORE ASSEMBLYGEN *************") - printProgram(program) +// println("*********** AST BEFORE ASSEMBLYGEN *************") +// printProgram(program) if (args.writeAssembly) { when (val result = writeAssembly(program, args.errors, args.outputDir, args.quietAssembler, compilationOptions)) { diff --git a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt index 03d11b61f..df017928c 100644 --- a/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt +++ b/compiler/src/prog8/compiler/astprocessing/StatementReorderer.kt @@ -59,6 +59,14 @@ internal class StatementReorderer(val program: Program, return noModifications } val nextStmt = decl.nextSibling() + val nextAssign = nextStmt as? Assignment + if(nextAssign!=null && !nextAssign.isAugmentable) { + val target = nextAssign.target.identifier?.targetStatement(program) + if(target === decl) { + // an initializer assignment for a vardecl is already here + return noModifications + } + } val nextFor = nextStmt as? ForLoop val hasNextForWithThisLoopvar = nextFor?.loopVar?.nameInSource==listOf(decl.name) if (!hasNextForWithThisLoopvar) { diff --git a/compiler/test/TestOptimization.kt b/compiler/test/TestOptimization.kt index e070f24da..0eb0f01aa 100644 --- a/compiler/test/TestOptimization.kt +++ b/compiler/test/TestOptimization.kt @@ -633,14 +633,13 @@ class TestOptimization: FunSpec({ uword zz zz = 60 ubyte xx - xx = 0 xx = sin8u(xx) xx += 6 */ val stmts = result.program.entrypoint.statements - stmts.size shouldBe 8 + stmts.size shouldBe 7 stmts.filterIsInstance().size shouldBe 3 - stmts.filterIsInstance().size shouldBe 5 + stmts.filterIsInstance().size shouldBe 4 } test("only substitue assignments with 0 after a =0 initializer if it is the same variable") { @@ -666,6 +665,8 @@ class TestOptimization: FunSpec({ yy = 0 xx += 10 */ + printProgram(result.program) + val stmts = result.program.entrypoint.statements stmts.size shouldBe 7 stmts.filterIsInstance().size shouldBe 2 diff --git a/compiler/test/TestSubroutines.kt b/compiler/test/TestSubroutines.kt index ac56cdae0..88a43e025 100644 --- a/compiler/test/TestSubroutines.kt +++ b/compiler/test/TestSubroutines.kt @@ -206,14 +206,14 @@ class TestSubroutines: FunSpec({ val block = module.statements.single() as Block val thing = block.statements.filterIsInstance().single {it.name=="thing"} block.name shouldBe "main" - thing.statements.size shouldBe 11 // rr paramdecl, xx, xx assign, yy decl, yy init 0, yy assign, other, other assign 0, zz, zz assign, return + thing.statements.size shouldBe 10 // rr paramdecl, xx, xx assign, yy decl, yy assign, other, other assign 0, zz, zz assign, return val xx = thing.statements[1] as VarDecl withClue("vardecl init values must have been moved to separate assignments") { xx.value shouldBe null } val assignXX = thing.statements[2] as Assignment - val assignYY = thing.statements[5] as Assignment - val assignZZ = thing.statements[9] as Assignment + val assignYY = thing.statements[4] as Assignment + val assignZZ = thing.statements[8] as Assignment assignXX.target.identifier!!.nameInSource shouldBe listOf("xx") assignYY.target.identifier!!.nameInSource shouldBe listOf("yy") assignZZ.target.identifier!!.nameInSource shouldBe listOf("zz") diff --git a/examples/test.p8 b/examples/test.p8 index b1f07e8e4..d06525874 100644 --- a/examples/test.p8 +++ b/examples/test.p8 @@ -2,6 +2,14 @@ %zeropage basicsafe main { + ubyte @shared foo=99 + sub thing(uword rr) { + ubyte @shared xx = rr[1] ; should still work as var initializer that will be rewritten + ubyte @shared yy + yy = rr[2] + uword @shared other + ubyte @shared zz = other[3] + } sub start() { ubyte @shared xx repeat {