fix substituting 0 only if its actually the same variable that's substituted

This commit is contained in:
Irmen de Jong 2021-11-21 12:34:57 +01:00
parent dde4c751da
commit 8887e6af91
4 changed files with 65 additions and 43 deletions

View File

@ -216,7 +216,7 @@ class UnusedCodeRemover(private val program: Program,
val assign2 = stmtPairs[1] as? Assignment
if (assign1 != null && assign2 != null) {
val cvalue1 = assign1.value.constValue(program)
if(cvalue1!=null && cvalue1.number==0.0 && assign2.isAugmentable) {
if(cvalue1!=null && cvalue1.number==0.0 && assign2.target.isSameAs(assign1.target, program) && assign2.isAugmentable) {
val value2 = assign2.value
val zero = VarDecl.defaultZero(value2.inferType(program).getOr(DataType.UNDEFINED), value2.position)
when(value2) {

View File

@ -15,6 +15,7 @@ import prog8.ast.base.Position
import prog8.ast.expressions.*
import prog8.ast.statements.*
import prog8.compiler.BeforeAsmGenerationAstChanger
import prog8.compiler.printProgram
import prog8.compiler.target.C64Target
import prog8.compilerinterface.*
import prog8tests.helpers.*
@ -527,4 +528,42 @@ class TestOptimization: FunSpec({
stmts.filterIsInstance<VarDecl>().size shouldBe 3
stmts.filterIsInstance<Assignment>().size shouldBe 5
}
test("only substitue assignments with 0 after a =0 initializer if it is the same variable") {
val src="""
main {
sub start() {
uword @shared xx
xx = xx + 20 ; is same var so can be changed just fine into xx=20
uword @shared yy
xx = 20
yy = 0 ; is other var..
xx = xx+10 ; so this should not be changed into xx=10
}
}"""
val result = compileText(C64Target, optimize=true, src, writeAssembly=false).assertSuccess()
/*
expected result:
uword xx
xx = 20
uword yy
yy = 0
xx = 20
yy = 0
xx += 10
*/
val stmts = result.program.entrypoint.statements
stmts.size shouldBe 7
stmts.filterIsInstance<VarDecl>().size shouldBe 2
stmts.filterIsInstance<Assignment>().size shouldBe 5
val assignXX1 = stmts[1] as Assignment
assignXX1.target.identifier!!.nameInSource shouldBe listOf("xx")
assignXX1.value shouldBe NumericLiteralValue(DataType.UBYTE, 20.0, Position.DUMMY)
val assignXX2 = stmts.last() as Assignment
assignXX2.target.identifier!!.nameInSource shouldBe listOf("xx")
val xxValue = assignXX2.value as BinaryExpression
xxValue.operator shouldBe "+"
xxValue.left shouldBe IdentifierReference(listOf("xx"), Position.DUMMY)
xxValue.right shouldBe NumericLiteralValue(DataType.UBYTE, 10.0, Position.DUMMY)
}
})

View File

@ -3,6 +3,9 @@ TODO
For next compiler release (7.4)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
BUG: amiga example doesn't clear the whole screen when compiled with optimizations (ok without opts)
same sort of problem in bobs example, and highresbitmap, and testgfx2
...

View File

@ -4,50 +4,30 @@ main {
sub start() {
%asm {{
lda $d020
ldy $d021
sta $d020
sty $d021
lda $d020
ldy $d021
sta $d020
sty $d021
lda $d020
sta $d020
lda $d020
sta $d020
lda $d020
sta $d020
lda $d020
sta $d020
sta $d020
sta $d020
sta $d020
sta $d020
sta $d020
sta $d020
lda $c020
sta $c020
lda $c020
sta $c020
lda $c020
sta $c020
lda $c020
sta $c020
sta $c020
sta $c020
sta $c020
sta $c020
sta $c020
}}
repeat 100 {
random_rgb12()
txt.print_ubhex(target_red,false)
txt.print_ubhex(target_green,false)
txt.print_ubhex(target_blue,false)
txt.nl()
}
repeat {
}
}
ubyte target_red
ubyte target_green
ubyte target_blue
sub random_rgb12() {
do {
uword rr = rndw()
target_red = msb(rr) & 15
target_green = lsb(rr)
target_blue = target_green & 15
target_green >>= 4
} until target_red+target_green+target_blue >= 12
}
}