remove unneeded var inits when an assignment is already present

This commit is contained in:
Irmen de Jong 2021-12-25 23:30:09 +01:00
parent 4da4f96669
commit 67b0890a6e
5 changed files with 25 additions and 8 deletions

View File

@ -76,8 +76,8 @@ fun compileProgram(args: CompilerArguments): CompilationResult {
) )
postprocessAst(program, args.errors, compilationOptions) postprocessAst(program, args.errors, compilationOptions)
println("*********** AST BEFORE ASSEMBLYGEN *************") // println("*********** AST BEFORE ASSEMBLYGEN *************")
printProgram(program) // printProgram(program)
if (args.writeAssembly) { if (args.writeAssembly) {
when (val result = writeAssembly(program, args.errors, args.outputDir, args.quietAssembler, compilationOptions)) { when (val result = writeAssembly(program, args.errors, args.outputDir, args.quietAssembler, compilationOptions)) {

View File

@ -59,6 +59,14 @@ internal class StatementReorderer(val program: Program,
return noModifications return noModifications
} }
val nextStmt = decl.nextSibling() 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 nextFor = nextStmt as? ForLoop
val hasNextForWithThisLoopvar = nextFor?.loopVar?.nameInSource==listOf(decl.name) val hasNextForWithThisLoopvar = nextFor?.loopVar?.nameInSource==listOf(decl.name)
if (!hasNextForWithThisLoopvar) { if (!hasNextForWithThisLoopvar) {

View File

@ -633,14 +633,13 @@ class TestOptimization: FunSpec({
uword zz uword zz
zz = 60 zz = 60
ubyte xx ubyte xx
xx = 0
xx = sin8u(xx) xx = sin8u(xx)
xx += 6 xx += 6
*/ */
val stmts = result.program.entrypoint.statements val stmts = result.program.entrypoint.statements
stmts.size shouldBe 8 stmts.size shouldBe 7
stmts.filterIsInstance<VarDecl>().size shouldBe 3 stmts.filterIsInstance<VarDecl>().size shouldBe 3
stmts.filterIsInstance<Assignment>().size shouldBe 5 stmts.filterIsInstance<Assignment>().size shouldBe 4
} }
test("only substitue assignments with 0 after a =0 initializer if it is the same variable") { 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 yy = 0
xx += 10 xx += 10
*/ */
printProgram(result.program)
val stmts = result.program.entrypoint.statements val stmts = result.program.entrypoint.statements
stmts.size shouldBe 7 stmts.size shouldBe 7
stmts.filterIsInstance<VarDecl>().size shouldBe 2 stmts.filterIsInstance<VarDecl>().size shouldBe 2

View File

@ -206,14 +206,14 @@ class TestSubroutines: FunSpec({
val block = module.statements.single() as Block val block = module.statements.single() as Block
val thing = block.statements.filterIsInstance<Subroutine>().single {it.name=="thing"} val thing = block.statements.filterIsInstance<Subroutine>().single {it.name=="thing"}
block.name shouldBe "main" 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 val xx = thing.statements[1] as VarDecl
withClue("vardecl init values must have been moved to separate assignments") { withClue("vardecl init values must have been moved to separate assignments") {
xx.value shouldBe null xx.value shouldBe null
} }
val assignXX = thing.statements[2] as Assignment val assignXX = thing.statements[2] as Assignment
val assignYY = thing.statements[5] as Assignment val assignYY = thing.statements[4] as Assignment
val assignZZ = thing.statements[9] as Assignment val assignZZ = thing.statements[8] as Assignment
assignXX.target.identifier!!.nameInSource shouldBe listOf("xx") assignXX.target.identifier!!.nameInSource shouldBe listOf("xx")
assignYY.target.identifier!!.nameInSource shouldBe listOf("yy") assignYY.target.identifier!!.nameInSource shouldBe listOf("yy")
assignZZ.target.identifier!!.nameInSource shouldBe listOf("zz") assignZZ.target.identifier!!.nameInSource shouldBe listOf("zz")

View File

@ -2,6 +2,14 @@
%zeropage basicsafe %zeropage basicsafe
main { 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() { sub start() {
ubyte @shared xx ubyte @shared xx
repeat { repeat {