From eb74b8daa5f65d8a7b3b8c8ff7f41af60b4ee660 Mon Sep 17 00:00:00 2001 From: Irmen de Jong Date: Wed, 16 Jan 2019 21:18:00 +0100 Subject: [PATCH] got rid of useless opcode --- .../intermediate/IntermediateProgram.kt | 19 ------------------- .../src/prog8/compiler/intermediate/Opcode.kt | 1 - .../src/prog8/compiler/target/c64/AsmGen.kt | 16 +++++++++++++--- compiler/src/prog8/stackvm/StackVm.kt | 1 - 4 files changed, 13 insertions(+), 24 deletions(-) diff --git a/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt b/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt index 3bb2e6b50..9fb833575 100644 --- a/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt +++ b/compiler/src/prog8/compiler/intermediate/IntermediateProgram.kt @@ -43,7 +43,6 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap optimizeVariableCopying() optimizeMultipleSequentialLineInstrs() optimizeCallReturnIntoJump() - optimizeRestoreXSaveXIntoRepopX() // todo: add more optimizations to stackvm code optimizeRemoveNops() // must be done as the last step @@ -57,24 +56,6 @@ class IntermediateProgram(val name: String, var loadAddress: Int, val heap: Heap blk.instructions.removeIf { it.opcode== Opcode.NOP && it !is LabelInstr } } - private fun optimizeRestoreXSaveXIntoRepopX() { - // replace rrestorex+rsavex combo by only repopX - for(blk in blocks) { - val instructionsToReplace = mutableMapOf() - - blk.instructions.asSequence().withIndex().filter {it.value.opcode!=Opcode.LINE}.windowed(2).toList().forEach { - if(it[0].value.opcode==Opcode.RRESTOREX && it[1].value.opcode==Opcode.RSAVEX) { - instructionsToReplace[it[0].index] = Instruction(Opcode.REPOPX) - instructionsToReplace[it[1].index] = Instruction(Opcode.NOP) - } - } - - for (rins in instructionsToReplace) { - blk.instructions[rins.key] = rins.value - } - } - } - private fun optimizeCallReturnIntoJump() { // replaces call X followed by return, by jump X for(blk in blocks) { diff --git a/compiler/src/prog8/compiler/intermediate/Opcode.kt b/compiler/src/prog8/compiler/intermediate/Opcode.kt index fce9c1330..cdbb2bea0 100644 --- a/compiler/src/prog8/compiler/intermediate/Opcode.kt +++ b/compiler/src/prog8/compiler/intermediate/Opcode.kt @@ -261,7 +261,6 @@ enum class Opcode { RSAVEX, // save just X (the evaluation stack pointer) RRESTORE, // restore all internal registers and status flags RRESTOREX, // restore just X (the evaluation stack pointer) - REPOPX, // restore just X (the evaluation stack pointer) but store it again too (essentially not erasing the value that's saved on the stack) NOP, // do nothing BREAKPOINT, // breakpoint diff --git a/compiler/src/prog8/compiler/target/c64/AsmGen.kt b/compiler/src/prog8/compiler/target/c64/AsmGen.kt index 8e4f23ad7..ad0a2757d 100644 --- a/compiler/src/prog8/compiler/target/c64/AsmGen.kt +++ b/compiler/src/prog8/compiler/target/c64/AsmGen.kt @@ -422,7 +422,6 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, } Opcode.RSAVEX -> " sta ${C64Zeropage.SCRATCH_REG} | txa | pha | lda ${C64Zeropage.SCRATCH_REG}" Opcode.RRESTOREX -> " sta ${C64Zeropage.SCRATCH_REG} | pla | tax | lda ${C64Zeropage.SCRATCH_REG}" - Opcode.REPOPX -> " sta ${C64Zeropage.SCRATCH_REG} | pla | tax | pha | lda ${C64Zeropage.SCRATCH_REG}" Opcode.DISCARD_BYTE -> " inx" Opcode.DISCARD_WORD -> " inx" Opcode.DISCARD_FLOAT -> " inx | inx | inx" @@ -969,12 +968,14 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, } for(pattern in patterns.filter { it.sequence.size <= segment.size || (it.altSequence != null && it.altSequence.size <= segment.size)}) { - val opcodesList = opcodes.subList(0, pattern.sequence.size) + val opcodesList = if(pattern.sequence.size<=opcodes.size) opcodes.subList(0, pattern.sequence.size) else null + val opcodesListAlt = if(pattern.altSequence!=null && pattern.altSequence.size<=opcodes.size) opcodes.subList(0, pattern.altSequence.size) else null + if(pattern.sequence == opcodesList) { val asm = pattern.asm(segment) if(asm!=null) result.add(AsmFragment(asm, pattern.sequence.size)) - } else if(pattern.altSequence == opcodesList) { + } else if(opcodesListAlt!=null && pattern.altSequence == opcodesListAlt) { val asm = pattern.asm(segment) if(asm!=null) result.add(AsmFragment(asm, pattern.sequence.size)) @@ -3202,6 +3203,15 @@ class AsmGen(val options: CompilationOptions, val program: IntermediateProgram, """ }, + AsmPattern(listOf(Opcode.RRESTOREX, Opcode.LINE, Opcode.RSAVEX), listOf(Opcode.RRESTOREX, Opcode.RSAVEX)) { segment -> + """ + sta ${C64Zeropage.SCRATCH_REG} + pla + tax + pha + lda ${C64Zeropage.SCRATCH_REG} + """ + }, // various optimizable integer multiplications AsmPattern(listOf(Opcode.PUSH_BYTE, Opcode.MUL_B), listOf(Opcode.PUSH_BYTE, Opcode.MUL_UB)) { segment -> diff --git a/compiler/src/prog8/stackvm/StackVm.kt b/compiler/src/prog8/stackvm/StackVm.kt index cb8f6c105..f7c6cac2f 100644 --- a/compiler/src/prog8/stackvm/StackVm.kt +++ b/compiler/src/prog8/stackvm/StackVm.kt @@ -1487,7 +1487,6 @@ class StackVm(private var traceOutputFile: String?) { } Opcode.RSAVEX -> evalstack.push(variables["X"]) Opcode.RRESTOREX -> variables["X"] = evalstack.pop() - Opcode.REPOPX -> variables["X"] = evalstack.peek() Opcode.INLINE_ASSEMBLY -> throw VmExecutionException("stackVm doesn't support executing inline assembly code") Opcode.PUSH_ADDR_HEAPVAR -> { val heapId = variables[ins.callLabel]!!.heapId