mirror of
https://github.com/irmen/prog8.git
synced 2024-12-24 16:29:21 +00:00
remove unused variables from IR output
This commit is contained in:
parent
c560abedba
commit
c8531cbeb1
@ -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")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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() {
|
||||||
|
@ -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
|
|
||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
|
@ -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())
|
||||||
|
@ -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
|
||||||
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -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) {
|
||||||
|
Loading…
Reference in New Issue
Block a user