remove unused variables from IR output

This commit is contained in:
Irmen de Jong 2023-04-09 23:09:30 +02:00
parent c560abedba
commit c8531cbeb1
7 changed files with 28 additions and 10 deletions

View File

@ -58,7 +58,7 @@ class IRCodeGen(
val optimizer = IRPeepholeOptimizer(irProg) val optimizer = IRPeepholeOptimizer(irProg)
optimizer.optimize() optimizer.optimize()
val remover = IRUnusedCodeRemover(irProg, errors) val remover = IRUnusedCodeRemover(irProg, irSymbolTable, errors)
do { do {
val numRemoved = remover.optimize() val numRemoved = remover.optimize()
} while(numRemoved>0 && errors.noErrors()) } while(numRemoved>0 && errors.noErrors())
@ -115,10 +115,10 @@ class IRCodeGen(
block.children.firstOrNull { it is IRInlineAsmChunk }?.let { first-> block.children.firstOrNull { it is IRInlineAsmChunk }?.let { first->
first as IRInlineAsmChunk first as IRInlineAsmChunk
if(first.label==null) { if(first.label==null) {
val replacement = IRInlineAsmChunk(block.name, first.assembly, first.isIR, first.next) val replacement = IRInlineAsmChunk(block.label, first.assembly, first.isIR, first.next)
block.children.removeAt(0) block.children.removeAt(0)
block.children.add(0, replacement) block.children.add(0, replacement)
} else if(first.label != block.name) { } else if(first.label != block.label) {
throw AssemblyError("first chunk in block has label that differs from block name") throw AssemblyError("first chunk in block has label that differs from block name")
} }
} }

View File

@ -5,7 +5,11 @@ import prog8.code.core.SourceCode.Companion.libraryFilePrefix
import prog8.intermediate.* import prog8.intermediate.*
internal class IRUnusedCodeRemover(private val irprog: IRProgram, private val errors: IErrorReporter) { internal class IRUnusedCodeRemover(
private val irprog: IRProgram,
private val symbolTable: IRSymbolTable,
private val errors: IErrorReporter
) {
fun optimize(): Int { fun optimize(): Int {
val allLabeledChunks = mutableMapOf<String, IRCodeChunkBase>() val allLabeledChunks = mutableMapOf<String, IRCodeChunkBase>()
@ -25,6 +29,7 @@ internal class IRUnusedCodeRemover(private val irprog: IRProgram, private val er
errors.warn("unused subroutine ${sub.label}", sub.position) errors.warn("unused subroutine ${sub.label}", sub.position)
} }
block.children.remove(sub) block.children.remove(sub)
symbolTable.removeTree(sub.label)
numRemoved++ numRemoved++
} }
} }
@ -34,6 +39,7 @@ internal class IRUnusedCodeRemover(private val irprog: IRProgram, private val er
irprog.blocks.reversed().forEach { block -> irprog.blocks.reversed().forEach { block ->
if(block.isEmpty()) { if(block.isEmpty()) {
irprog.blocks.remove(block) irprog.blocks.remove(block)
symbolTable.removeTree(block.label)
numRemoved++ numRemoved++
} }
} }
@ -42,7 +48,7 @@ internal class IRUnusedCodeRemover(private val irprog: IRProgram, private val er
} }
private fun removeUnreachable(allLabeledChunks: MutableMap<String, IRCodeChunkBase>): Int { private fun removeUnreachable(allLabeledChunks: MutableMap<String, IRCodeChunkBase>): Int {
val entrypointSub = irprog.blocks.single { it.name=="main" }.children.single { it is IRSubroutine && it.label=="main.start" } val entrypointSub = irprog.blocks.single { it.label=="main" }.children.single { it is IRSubroutine && it.label=="main.start" }
val reachable = mutableSetOf((entrypointSub as IRSubroutine).chunks.first()) val reachable = mutableSetOf((entrypointSub as IRSubroutine).chunks.first())
fun grow() { fun grow() {

View File

@ -3,7 +3,7 @@ TODO
For next minor release For next minor release
^^^^^^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^^^^^^^^^^
remove unused variables from IR output, such as sys.wait.jiffies when never calling sys.wait
... ...

View File

@ -55,7 +55,7 @@ class IRFileWriter(private val irProgram: IRProgram, outfileOverride: Path?) {
private fun writeBlocks() { private fun writeBlocks() {
irProgram.blocks.forEach { block -> irProgram.blocks.forEach { block ->
xml.writeStartElement("BLOCK") xml.writeStartElement("BLOCK")
xml.writeAttribute("NAME", block.name) xml.writeAttribute("NAME", block.label)
xml.writeAttribute("ADDRESS", block.address?.toHex() ?: "") xml.writeAttribute("ADDRESS", block.address?.toHex() ?: "")
xml.writeAttribute("ALIGN", block.alignment.toString()) xml.writeAttribute("ALIGN", block.alignment.toString())
xml.writeAttribute("POS", block.position.toString()) xml.writeAttribute("POS", block.position.toString())

View File

@ -60,7 +60,7 @@ class IRProgram(val name: String,
} }
fun addBlock(block: IRBlock) { fun addBlock(block: IRBlock) {
require(blocks.all { it.name != block.name}) { "duplicate block ${block.name} ${block.position}" } require(blocks.all { it.label != block.label}) { "duplicate block ${block.label} ${block.position}" }
blocks.add(block) blocks.add(block)
} }
@ -238,7 +238,7 @@ class IRProgram(val name: String,
} }
class IRBlock( class IRBlock(
val name: String, val label: String,
val address: UInt?, val address: UInt?,
val alignment: BlockAlignment, val alignment: BlockAlignment,
val position: Position val position: Position

View File

@ -4,6 +4,7 @@ import prog8.code.*
import prog8.code.ast.PtVariable import prog8.code.ast.PtVariable
import prog8.code.core.DataType import prog8.code.core.DataType
import prog8.code.core.ZeropageWish import prog8.code.core.ZeropageWish
import prog8.code.core.internedStringsModuleName
// In the Intermediate Representation, all nesting has been removed. // In the Intermediate Representation, all nesting has been removed.
@ -120,4 +121,15 @@ class IRSymbolTable(sourceSt: SymbolTable?) {
} }
fun getAsmSymbols(): Map<String, String> = asmSymbols fun getAsmSymbols(): Map<String, String> = asmSymbols
fun removeTree(label: String) {
val prefix = "$label."
val vars = table.filter { it.key.startsWith(prefix) }
vars.forEach {
// check if attempt is made to delete interned strings, if so, refuse that.
if(!it.key.startsWith(internedStringsModuleName)) {
table.remove(it.key)
}
}
}
} }

View File

@ -36,7 +36,7 @@ class VmProgramLoader {
val chunkReplacements = mutableListOf<Pair<IRCodeChunkBase, IRCodeChunk>>() val chunkReplacements = mutableListOf<Pair<IRCodeChunkBase, IRCodeChunk>>()
irProgram.blocks.forEach { block -> irProgram.blocks.forEach { block ->
if(block.address!=null) if(block.address!=null)
throw IRParseException("blocks cannot have a load address for vm: ${block.name}") throw IRParseException("blocks cannot have a load address for vm: ${block.label}")
block.children.forEach { child -> block.children.forEach { child ->
when(child) { when(child) {