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)
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)) {

View File

@ -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) {

View File

@ -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<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") {
@ -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<VarDecl>().size shouldBe 2

View File

@ -206,14 +206,14 @@ class TestSubroutines: FunSpec({
val block = module.statements.single() as Block
val thing = block.statements.filterIsInstance<Subroutine>().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")

View File

@ -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 {