diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt index 453d80b14..72f590f64 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRCodeGen.kt @@ -139,7 +139,7 @@ class IRCodeGen( // note: we do still export the memory mapped symbols so a code generator can use those // for instance when a piece of inlined assembly references them. val replacements = mutableListOf>() - irProg.blocks.asSequence().flatMap { it.children.filterIsInstance() }.flatMap { it.chunks }.forEach { chunk -> + irProg.foreachCodeChunk { chunk -> chunk.instructions.withIndex().forEach { (idx, instr) -> val symbolExpr = instr.labelSymbol diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt index 1e33a44ad..e4cfcef26 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRPeepholeOptimizer.kt @@ -23,7 +23,7 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) { } private fun optimizeOnlyJoinChunks() { - irprog.blocks.asSequence().flatMap { it.children.filterIsInstance() }.forEach { sub -> + irprog.foreachSub { sub -> joinChunks(sub) removeEmptyChunks(sub) joinChunks(sub) @@ -32,7 +32,7 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) { } private fun peepholeOptimize() { - irprog.blocks.asSequence().flatMap { it.children.filterIsInstance() }.forEach { sub -> + irprog.foreachSub { sub -> joinChunks(sub) removeEmptyChunks(sub) joinChunks(sub) diff --git a/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt b/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt index c5d43b248..ce063a328 100644 --- a/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt +++ b/codeGenIntermediate/src/prog8/codegen/intermediate/IRUnusedCodeRemover.kt @@ -26,10 +26,8 @@ class IRUnusedCodeRemover( private fun removeUnusedSubroutines(): Int { val allLabeledChunks = mutableMapOf() - irprog.blocks.asSequence().flatMap { it.children.filterIsInstance() }.forEach { sub -> - sub.chunks.forEach { chunk -> - chunk.label?.let { allLabeledChunks[it] = chunk } - } + irprog.foreachCodeChunk { chunk -> + chunk.label?.let { allLabeledChunks[it] = chunk } } var numRemoved = removeSimpleUnlinked(allLabeledChunks) + removeUnreachable(allLabeledChunks) @@ -97,12 +95,10 @@ class IRUnusedCodeRemover( } // check if asmsub is linked or called from another regular subroutine - irprog.blocks.asSequence().flatMap { it.children.filterIsInstance() }.forEach { sub -> - sub.chunks.forEach { chunk -> - chunk.instructions.forEach { - it.labelSymbol?.let { label -> allSubs[label]?.let { cc -> linkedAsmSubs += cc } } - // note: branchTarget can't yet point to another IRAsmSubroutine, so do nothing when it's set - } + irprog.foreachCodeChunk { chunk -> + chunk.instructions.forEach { + it.labelSymbol?.let { label -> allSubs[label]?.let { cc -> linkedAsmSubs += cc } } + // note: branchTarget can't yet point to another IRAsmSubroutine, so do nothing when it's set } } @@ -154,19 +150,17 @@ class IRUnusedCodeRemover( private fun removeSimpleUnlinked(allLabeledChunks: Map): Int { val linkedChunks = mutableSetOf() - irprog.blocks.asSequence().flatMap { it.children.filterIsInstance() }.forEach { sub -> - sub.chunks.forEach { chunk -> - chunk.next?.let { next -> linkedChunks += next } - chunk.instructions.forEach { - if(it.branchTarget==null) { - it.labelSymbol?.let { label -> allLabeledChunks[label]?.let { cc -> linkedChunks += cc } } - } else { - linkedChunks += it.branchTarget!! - } + irprog.foreachCodeChunk { chunk -> + chunk.next?.let { next -> linkedChunks += next } + chunk.instructions.forEach { + if(it.branchTarget==null) { + it.labelSymbol?.let { label -> allLabeledChunks[label]?.let { cc -> linkedChunks += cc } } + } else { + linkedChunks += it.branchTarget!! } - if (chunk.label == "main.start") - linkedChunks += chunk } + if (chunk.label == "main.start") + linkedChunks += chunk } return removeUnlinkedChunks(linkedChunks) @@ -176,7 +170,7 @@ class IRUnusedCodeRemover( linkedChunks: Set ): Int { var numRemoved = 0 - irprog.blocks.asSequence().flatMap { it.children.filterIsInstance() }.forEach { sub -> + irprog.foreachSub { sub -> sub.chunks.withIndex().reversed().forEach { (index, chunk) -> if (chunk !in linkedChunks) { if (chunk === sub.chunks[0]) { diff --git a/codeGenIntermediate/test/TestIRPeepholeOpt.kt b/codeGenIntermediate/test/TestIRPeepholeOpt.kt index 8ee8768e7..0a318a8ee 100644 --- a/codeGenIntermediate/test/TestIRPeepholeOpt.kt +++ b/codeGenIntermediate/test/TestIRPeepholeOpt.kt @@ -36,7 +36,7 @@ class TestIRPeepholeOpt: FunSpec({ return makeIRProgram(listOf(chunk)) } - fun IRProgram.chunks(): List = this.blocks.flatMap { it.children.filterIsInstance() }.flatMap { it.chunks } + fun IRProgram.chunks(): List = this.allSubs().flatMap { it.chunks }.toList() test("remove nops") { val irProg = makeIRProgram(listOf( diff --git a/docs/source/todo.rst b/docs/source/todo.rst index 780be5edd..638bc0861 100644 --- a/docs/source/todo.rst +++ b/docs/source/todo.rst @@ -16,7 +16,7 @@ For 9.0 major changes - [much work:] add special (u)word array type (or modifier such as @fast? ) that puts the array into memory as 2 separate byte-arrays 1 for LSB 1 for MSB -> allows for word arrays of length 256 and faster indexing this is an enormous amout of work, if this type is to be treated equally as existing (u)word , because all expression / lookup / assignment routines need to know about the distinction.... - So maybe only allow the bare essentials? (store, get, bitwise operations?) + So maybe only allow the bare essentials? (store, get, ++/--/+/-, bitwise operations?) - [much work:] more support for (64tass) SEGMENTS ? - (What, how, isn't current BSS support enough?) - Add a mechanism to allocate variables into golden ram (or segments really) (see GoldenRam class) diff --git a/intermediate/src/prog8/intermediate/IRProgram.kt b/intermediate/src/prog8/intermediate/IRProgram.kt index d83cb3abf..23b5a0881 100644 --- a/intermediate/src/prog8/intermediate/IRProgram.kt +++ b/intermediate/src/prog8/intermediate/IRProgram.kt @@ -55,6 +55,10 @@ class IRProgram(val name: String, val globalInits = IRCodeChunk(null, null) val blocks = mutableListOf() + fun allSubs(): Sequence = blocks.asSequence().flatMap { it.children.filterIsInstance() } + fun foreachSub(operation: (sub: IRSubroutine) -> Unit) = allSubs().forEach { operation(it) } + fun foreachCodeChunk(operation: (chunk: IRCodeChunkBase) -> Unit) = allSubs().flatMap { it.chunks }.forEach { operation(it) } + fun addGlobalInits(chunk: IRCodeChunk) { globalInits += chunk }