From e2c101206c3f9fe4694585ef480dfff67c13c6d9 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Tue, 14 Mar 2023 22:14:48 +0100 Subject: [PATCH] removed a problematic asm optimization step that could result in dysfunctional code when writing to I/O addresses --- codeCore/src/prog8/code/SymbolTable.kt | 10 +- .../src/prog8/codegen/cpu6502/AsmOptimizer.kt | 209 ------------------ docs/source/todo.rst | 2 - 3 files changed, 6 insertions(+), 215 deletions(-) diff --git a/codeCore/src/prog8/code/SymbolTable.kt b/codeCore/src/prog8/code/SymbolTable.kt index dd2672e9f..33e6eea95 100644 --- a/codeCore/src/prog8/code/SymbolTable.kt +++ b/codeCore/src/prog8/code/SymbolTable.kt @@ -17,11 +17,13 @@ class SymbolTable(astProgram: PtProgram) : StNode(astProgram.name, StNodeType.GL val flat: Map by lazy { val result = mutableMapOf() - fun flatten(node: StNode) { - result[node.scopedName] = node - node.children.values.forEach { flatten(it) } + fun collect(node: StNode) { + for(child in node.children) { + result[child.value.scopedName] = child.value + collect(child.value) + } } - children.values.forEach { flatten(it) } + collect(this) result } diff --git a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmOptimizer.kt b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmOptimizer.kt index 871151ea3..5b4eb73f3 100644 --- a/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmOptimizer.kt +++ b/codeGenCpu6502/src/prog8/codegen/cpu6502/AsmOptimizer.kt @@ -51,13 +51,6 @@ internal fun optimizeAssembly(lines: MutableList, machine: IMachineDefin } var linesByFourteen = getLinesBy(lines, 14) - mods = optimizeSameAssignments(linesByFourteen, machine, symbolTable) - if(mods.isNotEmpty()) { - apply(mods, lines) - linesByFourteen = getLinesBy(lines, 14) - numberOfOptimizations++ - } - mods = optimizeSamePointerIndexing(linesByFourteen) if(mods.isNotEmpty()) { apply(mods, lines) @@ -128,208 +121,6 @@ private fun optimizeUselessStackByteWrites(linesByFour: List>>, - machine: IMachineDefinition, - symbolTable: SymbolTable -): List { - - // Optimize sequential assignments of the same value to various targets (bytes, words, floats) - // the float one is the one that requires 2*7=14 lines of code to check... - // The better place to do this is in the Compiler instead and never create these types of assembly, but hey - - val mods = mutableListOf() - for (lines in linesByFourteen) { - val first = lines[0].value.trimStart() - val second = lines[1].value.trimStart() - val third = lines[2].value.trimStart() - val fourth = lines[3].value.trimStart() - val fifth = lines[4].value.trimStart() - val sixth = lines[5].value.trimStart() - val seventh = lines[6].value.trimStart() - val eighth = lines[7].value.trimStart() - - if(first.startsWith("lda") && second.startsWith("ldy") && third.startsWith("sta") && fourth.startsWith("sty") && - fifth.startsWith("lda") && sixth.startsWith("ldy") && seventh.startsWith("sta") && eighth.startsWith("sty")) { - val firstvalue = first.substring(4) - val secondvalue = second.substring(4) - val thirdvalue = fifth.substring(4) - val fourthvalue = sixth.substring(4) - if(firstvalue==thirdvalue && secondvalue==fourthvalue) { - // lda/ldy sta/sty twice the same word --> remove second lda/ldy pair (fifth and sixth lines) - val address1 = getAddressArg(first, symbolTable) - val address2 = getAddressArg(second, symbolTable) - if(address1==null || address2==null || (!machine.isIOAddress(address1) && !machine.isIOAddress(address2))) { - mods.add(Modification(lines[4].index, true, null)) - mods.add(Modification(lines[5].index, true, null)) - } - } - } - - if(first.startsWith("lda") && second.startsWith("sta") && third.startsWith("lda") && fourth.startsWith("sta")) { - val firstvalue = first.substring(4) - val secondvalue = third.substring(4) - if(firstvalue==secondvalue) { - // lda value / sta ? / lda same-value / sta ? -> remove second lda (third line) - val address = getAddressArg(first, symbolTable) - if(address==null || !machine.isIOAddress(address)) - mods.add(Modification(lines[2].index, true, null)) - } - } - - if(first.startsWith("lda") && second.startsWith("ldy") && third.startsWith("sta") && fourth.startsWith("sty") && - fifth.startsWith("lda") && sixth.startsWith("ldy") && - (seventh.startsWith("jsr floats.copy_float") || seventh.startsWith("jsr cx16flt.copy_float"))) { - - val nineth = lines[8].value.trimStart() - val tenth = lines[9].value.trimStart() - val eleventh = lines[10].value.trimStart() - val twelveth = lines[11].value.trimStart() - val thirteenth = lines[12].value.trimStart() - val fourteenth = lines[13].value.trimStart() - - if(eighth.startsWith("lda") && nineth.startsWith("ldy") && tenth.startsWith("sta") && eleventh.startsWith("sty") && - twelveth.startsWith("lda") && thirteenth.startsWith("ldy") && - (fourteenth.startsWith("jsr floats.copy_float") || fourteenth.startsWith("jsr cx16flt.copy_float"))) { - - if(first.substring(4) == eighth.substring(4) && second.substring(4)==nineth.substring(4)) { - // identical float init - mods.add(Modification(lines[7].index, true, null)) - mods.add(Modification(lines[8].index, true, null)) - mods.add(Modification(lines[9].index, true, null)) - mods.add(Modification(lines[10].index, true, null)) - } - } - } - - var overlappingMods = false - /* - sta prog8_lib.retval_intermX ; remove - sty prog8_lib.retval_intermY ; remove - lda prog8_lib.retval_intermX ; remove - ldy prog8_lib.retval_intermY ; remove - sta A1 - sty A2 - */ - if(first.isStoreReg() && second.isStoreReg() - && third.isLoadReg() && fourth.isLoadReg() - && fifth.isStoreReg() && sixth.isStoreReg()) { - val reg1 = first[2] - val reg2 = second[2] - val reg3 = third[2] - val reg4 = fourth[2] - val reg5 = fifth[2] - val reg6 = sixth[2] - if (reg1 == reg3 && reg1 == reg5 && reg2 == reg4 && reg2 == reg6) { - val firstvalue = first.substring(4) - val secondvalue = second.substring(4) - val thirdvalue = third.substring(4) - val fourthvalue = fourth.substring(4) - if(firstvalue.contains("prog8_lib.retval_interm") && secondvalue.contains("prog8_lib.retval_interm") - && firstvalue==thirdvalue && secondvalue==fourthvalue) { - mods.add(Modification(lines[0].index, true, null)) - mods.add(Modification(lines[1].index, true, null)) - mods.add(Modification(lines[2].index, true, null)) - mods.add(Modification(lines[3].index, true, null)) - overlappingMods = true - } - } - } - - /* - sta A1 - sty A2 - lda A1 ; can be removed - ldy A2 ; can be removed if not followed by a branch instuction - */ - if(!overlappingMods && first.isStoreReg() && second.isStoreReg() - && third.isLoadReg() && fourth.isLoadReg()) { - val reg1 = first[2] - val reg2 = second[2] - val reg3 = third[2] - val reg4 = fourth[2] - if(reg1==reg3 && reg2==reg4) { - val firstvalue = first.substring(4) - val secondvalue = second.substring(4) - val thirdvalue = third.substring(4) - val fourthvalue = fourth.substring(4) - if(firstvalue==thirdvalue && secondvalue == fourthvalue) { - val address = getAddressArg(first, symbolTable) - if(address==null || !machine.isIOAddress(address)) { - overlappingMods = true - mods.add(Modification(lines[2].index, true, null)) - if (!fifth.startsWith('b')) - mods.add(Modification(lines[3].index, true, null)) - } - } - } - } - - /* - sta A1 - sty A2 ; ... or stz - lda A1 ; can be removed if not followed by a branch instruction - */ - if(!overlappingMods && first.isStoreReg() && second.isStoreRegOrZero() - && third.isLoadReg() && !fourth.isBranch()) { - val reg1 = first[2] - val reg3 = third[2] - if(reg1==reg3) { - val firstvalue = first.substring(4) - val thirdvalue = third.substring(4) - if(firstvalue==thirdvalue) { - val address = getAddressArg(first, symbolTable) - if(address==null || !machine.isIOAddress(address)) { - overlappingMods = true - mods.add(Modification(lines[2].index, true, null)) - } - } - } - } - - /* - sta A1 - ldy A1 ; make tay - sta A1 ; remove - */ - if(!overlappingMods && first.startsWith("sta") && second.isLoadReg() - && third.startsWith("sta") && second.length>4) { - val firstvalue = first.substring(4) - val secondvalue = second.substring(4) - val thirdvalue = third.substring(4) - if(firstvalue==secondvalue && firstvalue==thirdvalue) { - val address = getAddressArg(first, symbolTable) - if(address==null || !machine.isIOAddress(address)) { - overlappingMods = true - val reg2 = second[2] - mods.add(Modification(lines[1].index, false, " ta$reg2")) - mods.add(Modification(lines[2].index, true, null)) - } - } - } - - /* - sta A ; or stz double store, remove this first one - sta A ; or stz - */ - if(!overlappingMods && first.isStoreRegOrZero() && second.isStoreRegOrZero()) { - if(first[2]==second[2]) { - val firstvalue = first.substring(4) - val secondvalue = second.substring(4) - if(firstvalue==secondvalue) { - val address = getAddressArg(first, symbolTable) - if(address==null || !machine.isIOAddress(address)) { - overlappingMods = true - mods.add(Modification(lines[0].index, true, null)) - } - } - } - } - } - - return mods -} - private fun optimizeSamePointerIndexing(linesByFourteen: List>>): List { // Optimize same pointer indexing where for instance we load and store to the same ptr index in Y diff --git a/docs/source/todo.rst b/docs/source/todo.rst index c74135925..8e0499d74 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -3,8 +3,6 @@ TODO For next minor release ^^^^^^^^^^^^^^^^^^^^^^ -- IR: animals and textelite take more registers now than with 8.10 (code *is* smaller) see test.p8 - ...