IR handy sequence shortcut functions

This commit is contained in:
Irmen de Jong 2023-05-18 11:32:20 +02:00
parent 40f611664f
commit 91421b0c62
6 changed files with 25 additions and 27 deletions

View File

@ -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<Triple<IRCodeChunkBase, Int, UInt>>()
irProg.blocks.asSequence().flatMap { it.children.filterIsInstance<IRSubroutine>() }.flatMap { it.chunks }.forEach { chunk ->
irProg.foreachCodeChunk { chunk ->
chunk.instructions.withIndex().forEach {
(idx, instr) ->
val symbolExpr = instr.labelSymbol

View File

@ -23,7 +23,7 @@ class IRPeepholeOptimizer(private val irprog: IRProgram) {
}
private fun optimizeOnlyJoinChunks() {
irprog.blocks.asSequence().flatMap { it.children.filterIsInstance<IRSubroutine>() }.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<IRSubroutine>() }.forEach { sub ->
irprog.foreachSub { sub ->
joinChunks(sub)
removeEmptyChunks(sub)
joinChunks(sub)

View File

@ -26,10 +26,8 @@ class IRUnusedCodeRemover(
private fun removeUnusedSubroutines(): Int {
val allLabeledChunks = mutableMapOf<String, IRCodeChunkBase>()
irprog.blocks.asSequence().flatMap { it.children.filterIsInstance<IRSubroutine>() }.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<IRSubroutine>() }.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<String, IRCodeChunkBase>): Int {
val linkedChunks = mutableSetOf<IRCodeChunkBase>()
irprog.blocks.asSequence().flatMap { it.children.filterIsInstance<IRSubroutine>() }.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<IRCodeChunkBase>
): Int {
var numRemoved = 0
irprog.blocks.asSequence().flatMap { it.children.filterIsInstance<IRSubroutine>() }.forEach { sub ->
irprog.foreachSub { sub ->
sub.chunks.withIndex().reversed().forEach { (index, chunk) ->
if (chunk !in linkedChunks) {
if (chunk === sub.chunks[0]) {

View File

@ -36,7 +36,7 @@ class TestIRPeepholeOpt: FunSpec({
return makeIRProgram(listOf(chunk))
}
fun IRProgram.chunks(): List<IRCodeChunkBase> = this.blocks.flatMap { it.children.filterIsInstance<IRSubroutine>() }.flatMap { it.chunks }
fun IRProgram.chunks(): List<IRCodeChunkBase> = this.allSubs().flatMap { it.chunks }.toList()
test("remove nops") {
val irProg = makeIRProgram(listOf(

View File

@ -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)

View File

@ -55,6 +55,10 @@ class IRProgram(val name: String,
val globalInits = IRCodeChunk(null, null)
val blocks = mutableListOf<IRBlock>()
fun allSubs(): Sequence<IRSubroutine> = blocks.asSequence().flatMap { it.children.filterIsInstance<IRSubroutine>() }
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
}